40
40
import org .springframework .data .mapping .Association ;
41
41
import org .springframework .data .mapping .AssociationHandler ;
42
42
import org .springframework .data .mapping .MappingException ;
43
+ import org .springframework .data .mapping .PersistentEntity ;
43
44
import org .springframework .data .mapping .PersistentProperty ;
44
45
import org .springframework .data .mapping .PropertyHandler ;
45
46
import org .springframework .data .mongodb .core .index .MongoPersistentEntityIndexResolver .CycleGuard .Path ;
62
63
import org .springframework .util .Assert ;
63
64
import org .springframework .util .ClassUtils ;
64
65
import org .springframework .util .NumberUtils ;
66
+ import org .springframework .util .ObjectUtils ;
65
67
import org .springframework .util .StringUtils ;
66
68
67
69
/**
@@ -356,10 +358,10 @@ protected IndexDefinitionHolder createCompoundIndexDefinition(String dotPath, St
356
358
MongoPersistentEntity <?> entity ) {
357
359
358
360
CompoundIndexDefinition indexDefinition = new CompoundIndexDefinition (
359
- resolveCompoundIndexKeyFromStringDefinition (dotPath , index .def ()));
361
+ resolveCompoundIndexKeyFromStringDefinition (dotPath , index .def (), entity ));
360
362
361
363
if (!index .useGeneratedName ()) {
362
- indexDefinition .named (pathAwareIndexName (index .name (), dotPath , null ));
364
+ indexDefinition .named (pathAwareIndexName (index .name (), dotPath , entity , null ));
363
365
}
364
366
365
367
if (index .unique ()) {
@@ -377,7 +379,8 @@ protected IndexDefinitionHolder createCompoundIndexDefinition(String dotPath, St
377
379
return new IndexDefinitionHolder (dotPath , indexDefinition , collection );
378
380
}
379
381
380
- private org .bson .Document resolveCompoundIndexKeyFromStringDefinition (String dotPath , String keyDefinitionString ) {
382
+ private org .bson .Document resolveCompoundIndexKeyFromStringDefinition (String dotPath , String keyDefinitionString ,
383
+ PersistentEntity <?, ?> entity ) {
381
384
382
385
if (!StringUtils .hasText (dotPath ) && !StringUtils .hasText (keyDefinitionString )) {
383
386
throw new InvalidDataAccessApiUsageException ("Cannot create index on root level for empty keys." );
@@ -387,7 +390,12 @@ private org.bson.Document resolveCompoundIndexKeyFromStringDefinition(String dot
387
390
return new org .bson .Document (dotPath , 1 );
388
391
}
389
392
390
- org .bson .Document dbo = org .bson .Document .parse (keyDefinitionString );
393
+ Object keyDefToUse = evaluatePotentialTemplateExpression (keyDefinitionString ,
394
+ getEvaluationContextForProperty (entity ));
395
+
396
+ org .bson .Document dbo = (keyDefToUse instanceof org .bson .Document ) ? (org .bson .Document ) keyDefToUse
397
+ : org .bson .Document .parse (ObjectUtils .nullSafeToString (keyDefToUse ));
398
+
391
399
if (!StringUtils .hasText (dotPath )) {
392
400
return dbo ;
393
401
}
@@ -423,7 +431,7 @@ protected IndexDefinitionHolder createIndexDefinition(String dotPath, String col
423
431
IndexDirection .ASCENDING .equals (index .direction ()) ? Sort .Direction .ASC : Sort .Direction .DESC );
424
432
425
433
if (!index .useGeneratedName ()) {
426
- indexDefinition .named (pathAwareIndexName (index .name (), dotPath , persitentProperty ));
434
+ indexDefinition .named (pathAwareIndexName (index .name (), dotPath , persitentProperty . getOwner (), persitentProperty ));
427
435
}
428
436
429
437
if (index .unique ()) {
@@ -446,21 +454,12 @@ protected IndexDefinitionHolder createIndexDefinition(String dotPath, String col
446
454
447
455
if (index .expireAfterSeconds () >= 0 ) {
448
456
throw new IllegalStateException (String .format (
449
- "@Indexed already defines an expiration timeout of %s sec. via Indexed#expireAfterSeconds. Please make to use either expireAfterSeconds or expireAfter." , index .expireAfterSeconds ()));
450
- }
451
-
452
- EvaluationContext ctx = getEvaluationContext ();
453
-
454
- if (persitentProperty .getOwner () instanceof BasicMongoPersistentEntity ) {
455
-
456
- EvaluationContext contextFromEntity = ((BasicMongoPersistentEntity <?>) persitentProperty .getOwner ())
457
- .getEvaluationContext (null );
458
- if (contextFromEntity != null && !EvaluationContextProvider .DEFAULT .equals (contextFromEntity )) {
459
- ctx = contextFromEntity ;
460
- }
457
+ "@Indexed already defines an expiration timeout of %s sec. via Indexed#expireAfterSeconds. Please make to use either expireAfterSeconds or expireAfter." ,
458
+ index .expireAfterSeconds ()));
461
459
}
462
460
463
- Duration timeout = computeIndexTimeout (index .expireAfter (), ctx );
461
+ Duration timeout = computeIndexTimeout (index .expireAfter (),
462
+ getEvaluationContextForProperty (persitentProperty .getOwner ()));
464
463
if (!timeout .isZero () && !timeout .isNegative ()) {
465
464
indexDefinition .expire (timeout );
466
465
}
@@ -479,6 +478,27 @@ protected EvaluationContext getEvaluationContext() {
479
478
return evaluationContextProvider .getEvaluationContext (null );
480
479
}
481
480
481
+ /**
482
+ * Get the {@link EvaluationContext} for a given {@link PersistentEntity entity} the default one.
483
+ *
484
+ * @param persistentEntity can be {@literal null}
485
+ * @return
486
+ */
487
+ private EvaluationContext getEvaluationContextForProperty (@ Nullable PersistentEntity <?, ?> persistentEntity ) {
488
+
489
+ if (persistentEntity == null || !(persistentEntity instanceof BasicMongoPersistentEntity )) {
490
+ return getEvaluationContext ();
491
+ }
492
+
493
+ EvaluationContext contextFromEntity = ((BasicMongoPersistentEntity <?>) persistentEntity ).getEvaluationContext (null );
494
+
495
+ if (contextFromEntity != null && !EvaluationContextProvider .DEFAULT .equals (contextFromEntity )) {
496
+ return contextFromEntity ;
497
+ }
498
+
499
+ return getEvaluationContext ();
500
+ }
501
+
482
502
/**
483
503
* Set the {@link EvaluationContextProvider} used for obtaining the {@link EvaluationContext} used to compute
484
504
* {@link org.springframework.expression.spel.standard.SpelExpression expressions}.
@@ -514,17 +534,22 @@ protected IndexDefinitionHolder createGeoSpatialIndexDefinition(String dotPath,
514
534
indexDefinition .withMin (index .min ()).withMax (index .max ());
515
535
516
536
if (!index .useGeneratedName ()) {
517
- indexDefinition .named (pathAwareIndexName (index .name (), dotPath , persistentProperty ));
537
+ indexDefinition
538
+ .named (pathAwareIndexName (index .name (), dotPath , persistentProperty .getOwner (), persistentProperty ));
518
539
}
519
540
520
541
indexDefinition .typed (index .type ()).withBucketSize (index .bucketSize ()).withAdditionalField (index .additionalField ());
521
542
522
543
return new IndexDefinitionHolder (dotPath , indexDefinition , collection );
523
544
}
524
545
525
- private String pathAwareIndexName (String indexName , String dotPath , @ Nullable MongoPersistentProperty property ) {
546
+ private String pathAwareIndexName (String indexName , String dotPath , @ Nullable PersistentEntity <?, ?> entity ,
547
+ @ Nullable MongoPersistentProperty property ) {
526
548
527
- String nameToUse = StringUtils .hasText (indexName ) ? indexName : "" ;
549
+ String nameToUse = StringUtils .hasText (indexName )
550
+ ? ObjectUtils
551
+ .nullSafeToString (evaluatePotentialTemplateExpression (indexName , getEvaluationContextForProperty (entity )))
552
+ : "" ;
528
553
529
554
if (!StringUtils .hasText (dotPath ) || (property != null && dotPath .equals (property .getFieldName ()))) {
530
555
return StringUtils .hasText (nameToUse ) ? nameToUse : dotPath ;
@@ -582,7 +607,17 @@ private void resolveAndAddIndexesForAssociation(Association<MongoPersistentPrope
582
607
*/
583
608
private static Duration computeIndexTimeout (String timeoutValue , EvaluationContext evaluationContext ) {
584
609
585
- String val = evaluatePotentialTemplateExpression (timeoutValue , evaluationContext );
610
+ Object evaluatedTimeout = evaluatePotentialTemplateExpression (timeoutValue , evaluationContext );
611
+
612
+ if (evaluatedTimeout == null ) {
613
+ return Duration .ZERO ;
614
+ }
615
+
616
+ if (evaluatedTimeout instanceof Duration ) {
617
+ return (Duration ) evaluatedTimeout ;
618
+ }
619
+
620
+ String val = evaluatedTimeout .toString ();
586
621
587
622
if (val == null ) {
588
623
return Duration .ZERO ;
@@ -611,15 +646,14 @@ private static Duration computeIndexTimeout(String timeoutValue, EvaluationConte
611
646
}
612
647
613
648
@ Nullable
614
- private static String evaluatePotentialTemplateExpression (String value , EvaluationContext evaluationContext ) {
649
+ private static Object evaluatePotentialTemplateExpression (String value , EvaluationContext evaluationContext ) {
615
650
616
651
Expression expression = PARSER .parseExpression (value , ParserContext .TEMPLATE_EXPRESSION );
617
652
if (expression instanceof LiteralExpression ) {
618
653
return value ;
619
654
}
620
655
621
- return expression .getValue (evaluationContext , String .class );
622
-
656
+ return expression .getValue (evaluationContext , Object .class );
623
657
}
624
658
625
659
/**
0 commit comments