1212import java .util .Arrays ;
1313import java .util .function .Consumer ;
1414
15+ import jakarta .persistence .Embeddable ;
1516import jakarta .persistence .Entity ;
1617import jakarta .persistence .EntityManagerFactory ;
1718import jakarta .persistence .Id ;
19+ import jakarta .persistence .MappedSuperclass ;
1820
1921import org .hibernate .search .documentation .testsupport .BackendConfigurations ;
2022import org .hibernate .search .documentation .testsupport .DocumentationSetupHelper ;
2123import org .hibernate .search .engine .backend .types .Projectable ;
2224import org .hibernate .search .engine .search .common .ValueConvert ;
2325import org .hibernate .search .engine .search .predicate .SearchPredicate ;
26+ import org .hibernate .search .engine .search .predicate .dsl .PredicateFinalStep ;
27+ import org .hibernate .search .engine .search .predicate .dsl .SearchPredicateFactory ;
28+ import org .hibernate .search .engine .search .reference .object .ObjectFieldReference ;
2429import org .hibernate .search .engine .search .reference .predicate .MatchPredicateFieldReference ;
2530import org .hibernate .search .engine .search .reference .projection .FieldProjectionFieldReference ;
2631import org .hibernate .search .mapper .orm .Search ;
2934import org .hibernate .search .mapper .orm .scope .SearchScopeProvider ;
3035import org .hibernate .search .mapper .orm .session .SearchSession ;
3136import org .hibernate .search .mapper .pojo .mapping .definition .annotation .FullTextField ;
37+ import org .hibernate .search .mapper .pojo .mapping .definition .annotation .GenericField ;
3238import org .hibernate .search .mapper .pojo .mapping .definition .annotation .Indexed ;
39+ import org .hibernate .search .mapper .pojo .mapping .definition .annotation .IndexedEmbedded ;
3340
3441import org .junit .jupiter .api .BeforeEach ;
3542import org .junit .jupiter .api .Test ;
@@ -45,7 +52,9 @@ class FieldReferenceIT {
4552 @ BeforeEach
4653 void setup () {
4754 entityManagerFactory = setupHelper .start ().setup ( EntityA .class , EntityB .class , EntityC .class ,
48- Entity2A .class , Entity2B .class , Entity2C .class );
55+ Entity2A .class , Entity2B .class , Entity2C .class ,
56+ ContainingA .class , ContainingB .class , EmbeddedThing1 .class , EmbeddedThing2 .class , EmbeddedThing3 .class
57+ );
4958 initData ();
5059 }
5160
@@ -126,6 +135,23 @@ void smoke2() {
126135 } );
127136 }
128137
138+ @ Test
139+ void smoke3 () {
140+
141+ withinSearchSession ( searchSession -> {
142+
143+ SearchScope <ContainingA_ , ContainingA > scope = ContainingA_ .scope .create ( searchSession );
144+
145+ assertThat (
146+ searchSession .search ( scope )
147+ .select ( f -> f .field ( ContainingA_ .a ) )
148+ .where ( f -> utilMethodForPredicate ( f ) )
149+ .fetchHits ( 20 )
150+ ).containsOnly ( "b" );
151+
152+ } );
153+ }
154+
129155 private void initData () {
130156 with ( entityManagerFactory ).runInTransaction ( entityManager -> {
131157 EntityA a = new EntityA ();
@@ -194,16 +220,18 @@ public static class EntityC extends EntityB {
194220
195221 }
196222
197- public static class EntityA_ {
198- public static ValueFieldReference1 <EntityA_ , String , String , String > stringA ;
199-
223+ public static class EntityA_ implements Properties_EntityA_ {
200224 public static HibernateOrmRootReferenceScope <EntityA_ , EntityA > scope ;
201225
202226 static {
203- stringA = ValueFieldReference1 .of ( "stringA" , EntityA_ .class , String .class , String .class , String .class );
204-
205227 scope = RootReferenceScopeImpl .of ( EntityA_ .class , EntityA .class );
206228 }
229+
230+ }
231+
232+ public interface Properties_EntityA_ {
233+ ValueFieldReference1 <EntityA_ , String , String , String > stringA =
234+ ValueFieldReference1 .of ( "stringA" , EntityA_ .class , String .class , String .class , String .class );
207235 }
208236
209237 public static class EntityB_ extends EntityA_ {
@@ -334,6 +362,178 @@ public static class Entity2C_ {
334362 }
335363 }
336364
365+ @ MappedSuperclass
366+ public static class MappedSuperclassThing {
367+ @ Id
368+ Long id ;
369+
370+ @ FullTextField (projectable = Projectable .YES )
371+ String a ;
372+ }
373+
374+ @ Indexed
375+ @ Entity
376+ public static class ContainingA extends MappedSuperclassThing {
377+ @ IndexedEmbedded
378+ EmbeddedThing1 e1 ;
379+ @ IndexedEmbedded
380+ EmbeddedThing1 e2 ;
381+ }
382+
383+ @ Embeddable
384+ public static class EmbeddedThing1 {
385+ @ FullTextField
386+ String a ;
387+ @ FullTextField
388+ String b ;
389+ // some other fields
390+ }
391+
392+ @ Embeddable
393+ public static class EmbeddedThing2 {
394+ @ FullTextField
395+ String a ;
396+ // some other fields maybe different from EmbeddedThing1
397+ }
398+
399+ @ Entity
400+ @ Indexed
401+ public static class ContainingB extends MappedSuperclassThing {
402+ @ IndexedEmbedded
403+ EmbeddedThing3 e3 ;
404+ }
405+
406+ @ Embeddable
407+ public static class EmbeddedThing3 {
408+ @ GenericField
409+ Integer a ;
410+ // some other fields maybe different from EmbeddedThing1/EmbeddedThing2
411+ }
412+
413+
414+ interface Property_String_a_ {
415+ ValueFieldReference1 <Property_String_a_ , String , String , String > a =
416+ ValueFieldReference1 .of ( "a" , Property_String_a_ .class , String .class , String .class , String .class );
417+ }
418+
419+ interface Property_String_b_ {
420+ ValueFieldReference1 <Property_String_b_ , String , String , String > b =
421+ ValueFieldReference1 .of ( "b" , Property_String_b_ .class , String .class , String .class , String .class );
422+ }
423+
424+ interface Property_Integer_a_ {
425+ ValueFieldReference1 <Property_Integer_a_ , Integer , Integer , Integer > a =
426+ ValueFieldReference1 .of ( "a" , Property_Integer_a_ .class , Integer .class , Integer .class , Integer .class );
427+ }
428+
429+ public static class MappedSuperclassThing_ implements Property_String_a_ {
430+
431+ public static HibernateOrmRootReferenceScope <MappedSuperclassThing_ , MappedSuperclassThing > scope ;
432+
433+ static {
434+ //a = ValueFieldReference1.of( "a", MappedSuperclassThing_.class, String.class, String.class, String.class );
435+
436+ scope = RootReferenceScopeImpl .of ( MappedSuperclassThing_ .class , MappedSuperclassThing .class );
437+ }
438+ }
439+
440+ public static class ContainingA_ extends MappedSuperclassThing_ {
441+ public static e1_ .Absolute e1 ;
442+ public static e2_ .Absolute e2 ;
443+
444+ public static HibernateOrmRootReferenceScope <ContainingA_ , ContainingA > scope ;
445+
446+ static {
447+ e1 = new e1_ .Absolute ();
448+ e2 = new e2_ .Absolute ();
449+
450+ scope = RootReferenceScopeImpl .of ( ContainingA_ .class , ContainingA .class );
451+ }
452+
453+ public static class e1_ implements ObjectFieldReference <ContainingA_ >, Property_String_a_ , Property_String_b_ {
454+
455+ @ Override
456+ public String absolutePath () {
457+ return "e1" ;
458+ }
459+
460+ @ Override
461+ public Class <ContainingA_ > scopeRootType () {
462+ return ContainingA_ .class ;
463+ }
464+
465+ static class Absolute extends e1_ {
466+ public static ValueFieldReference1 <ContainingA_ , String , String , String > a ;
467+ public static ValueFieldReference1 <ContainingA_ , String , String , String > b ;
468+
469+ static {
470+ a = ValueFieldReference1 .of ( "e1.a" , ContainingA_ .class , String .class , String .class , String .class );
471+ b = ValueFieldReference1 .of ( "e1.b" , ContainingA_ .class , String .class , String .class , String .class );
472+ }
473+ }
474+ }
475+
476+ public static class e2_ implements ObjectFieldReference <ContainingA_ >, Property_String_a_ , Property_String_b_ {
477+
478+ @ Override
479+ public String absolutePath () {
480+ return "e2" ;
481+ }
482+
483+ @ Override
484+ public Class <ContainingA_ > scopeRootType () {
485+ return ContainingA_ .class ;
486+ }
487+
488+ static class Absolute extends e2_ {
489+ public static ValueFieldReference1 <ContainingA_ , String , String , String > a ;
490+ public static ValueFieldReference1 <ContainingA_ , String , String , String > b ;
491+
492+ static {
493+ a = ValueFieldReference1 .of ( "e2.a" , ContainingA_ .class , String .class , String .class , String .class );
494+ b = ValueFieldReference1 .of ( "e2.b" , ContainingA_ .class , String .class , String .class , String .class );
495+ }
496+ }
497+ }
498+ }
499+
500+ public static class ContainingB_ extends MappedSuperclassThing_ {
501+ public static e3_ .Absolute e3 ;
502+
503+ public static HibernateOrmRootReferenceScope <ContainingB_ , ContainingB > scope ;
504+
505+ static {
506+ e3 = new e3_ .Absolute ();
507+
508+ scope = RootReferenceScopeImpl .of ( ContainingB_ .class , ContainingB .class );
509+ }
510+
511+ public static class e3_ implements ObjectFieldReference <ContainingB_ >, Property_Integer_a_ {
512+
513+ @ Override
514+ public String absolutePath () {
515+ return "e3" ;
516+ }
517+
518+ @ Override
519+ public Class <ContainingB_ > scopeRootType () {
520+ return ContainingB_ .class ;
521+ }
522+
523+ public static class Absolute extends e3_ {
524+ public static ValueFieldReference1 <ContainingB_ , Integer , Integer , Integer > a ;
525+
526+ static {
527+ a = ValueFieldReference1 .of ( "e3.a" , ContainingB_ .class , Integer .class , Integer .class , Integer .class );
528+ }
529+ }
530+ }
531+ }
532+
533+ public static PredicateFinalStep utilMethodForPredicate (SearchPredicateFactory <? extends Property_String_a_ > factory ) {
534+ return factory .match ().field ( Property_String_a_ .a ).matching ( "a" );
535+ }
536+
337537
338538 public static class ValueFieldReference1 <E , T , V , P > extends TypedFieldReference1 <E , T , P > {
339539
0 commit comments