1010import java .util .Arrays ;
1111import java .util .function .Consumer ;
1212
13+ import jakarta .persistence .Embeddable ;
1314import jakarta .persistence .Entity ;
1415import jakarta .persistence .EntityManagerFactory ;
1516import jakarta .persistence .Id ;
17+ import jakarta .persistence .MappedSuperclass ;
1618
1719import org .hibernate .search .documentation .testsupport .BackendConfigurations ;
1820import org .hibernate .search .documentation .testsupport .DocumentationSetupHelper ;
1921import org .hibernate .search .engine .backend .types .Projectable ;
2022import org .hibernate .search .engine .search .common .ValueConvert ;
2123import org .hibernate .search .engine .search .predicate .SearchPredicate ;
24+ import org .hibernate .search .engine .search .predicate .dsl .PredicateFinalStep ;
25+ import org .hibernate .search .engine .search .predicate .dsl .SearchPredicateFactory ;
26+ import org .hibernate .search .engine .search .reference .object .ObjectFieldReference ;
2227import org .hibernate .search .engine .search .reference .predicate .MatchPredicateFieldReference ;
2328import org .hibernate .search .engine .search .reference .projection .FieldProjectionFieldReference ;
2429import org .hibernate .search .mapper .orm .Search ;
2732import org .hibernate .search .mapper .orm .scope .SearchScopeProvider ;
2833import org .hibernate .search .mapper .orm .session .SearchSession ;
2934import org .hibernate .search .mapper .pojo .mapping .definition .annotation .FullTextField ;
35+ import org .hibernate .search .mapper .pojo .mapping .definition .annotation .GenericField ;
3036import org .hibernate .search .mapper .pojo .mapping .definition .annotation .Indexed ;
37+ import org .hibernate .search .mapper .pojo .mapping .definition .annotation .IndexedEmbedded ;
3138
3239import org .junit .jupiter .api .BeforeEach ;
3340import org .junit .jupiter .api .Test ;
@@ -43,7 +50,9 @@ class FieldReferenceIT {
4350 @ BeforeEach
4451 void setup () {
4552 entityManagerFactory = setupHelper .start ().setup ( EntityA .class , EntityB .class , EntityC .class ,
46- Entity2A .class , Entity2B .class , Entity2C .class );
53+ Entity2A .class , Entity2B .class , Entity2C .class ,
54+ ContainingA .class , ContainingB .class , EmbeddedThing1 .class , EmbeddedThing2 .class , EmbeddedThing3 .class
55+ );
4756 initData ();
4857 }
4958
@@ -124,6 +133,23 @@ void smoke2() {
124133 } );
125134 }
126135
136+ @ Test
137+ void smoke3 () {
138+
139+ withinSearchSession ( searchSession -> {
140+
141+ SearchScope <ContainingA_ , ContainingA > scope = ContainingA_ .scope .create ( searchSession );
142+
143+ assertThat (
144+ searchSession .search ( scope )
145+ .select ( f -> f .field ( ContainingA_ .a ) )
146+ .where ( f -> utilMethodForPredicate ( f ) )
147+ .fetchHits ( 20 )
148+ ).containsOnly ( "b" );
149+
150+ } );
151+ }
152+
127153 private void initData () {
128154 with ( entityManagerFactory ).runInTransaction ( entityManager -> {
129155 EntityA a = new EntityA ();
@@ -192,16 +218,18 @@ public static class EntityC extends EntityB {
192218
193219 }
194220
195- public static class EntityA_ {
196- public static ValueFieldReference1 <EntityA_ , String , String , String > stringA ;
197-
221+ public static class EntityA_ implements Properties_EntityA_ {
198222 public static HibernateOrmRootReferenceScope <EntityA_ , EntityA > scope ;
199223
200224 static {
201- stringA = ValueFieldReference1 .of ( "stringA" , EntityA_ .class , String .class , String .class , String .class );
202-
203225 scope = RootReferenceScopeImpl .of ( EntityA_ .class , EntityA .class );
204226 }
227+
228+ }
229+
230+ public interface Properties_EntityA_ {
231+ ValueFieldReference1 <EntityA_ , String , String , String > stringA =
232+ ValueFieldReference1 .of ( "stringA" , EntityA_ .class , String .class , String .class , String .class );
205233 }
206234
207235 public static class EntityB_ extends EntityA_ {
@@ -332,6 +360,178 @@ public static class Entity2C_ {
332360 }
333361 }
334362
363+ @ MappedSuperclass
364+ public static class MappedSuperclassThing {
365+ @ Id
366+ Long id ;
367+
368+ @ FullTextField (projectable = Projectable .YES )
369+ String a ;
370+ }
371+
372+ @ Indexed
373+ @ Entity
374+ public static class ContainingA extends MappedSuperclassThing {
375+ @ IndexedEmbedded
376+ EmbeddedThing1 e1 ;
377+ @ IndexedEmbedded
378+ EmbeddedThing1 e2 ;
379+ }
380+
381+ @ Embeddable
382+ public static class EmbeddedThing1 {
383+ @ FullTextField
384+ String a ;
385+ @ FullTextField
386+ String b ;
387+ // some other fields
388+ }
389+
390+ @ Embeddable
391+ public static class EmbeddedThing2 {
392+ @ FullTextField
393+ String a ;
394+ // some other fields maybe different from EmbeddedThing1
395+ }
396+
397+ @ Entity
398+ @ Indexed
399+ public static class ContainingB extends MappedSuperclassThing {
400+ @ IndexedEmbedded
401+ EmbeddedThing3 e3 ;
402+ }
403+
404+ @ Embeddable
405+ public static class EmbeddedThing3 {
406+ @ GenericField
407+ Integer a ;
408+ // some other fields maybe different from EmbeddedThing1/EmbeddedThing2
409+ }
410+
411+
412+ interface Property_String_a_ {
413+ ValueFieldReference1 <Property_String_a_ , String , String , String > a =
414+ ValueFieldReference1 .of ( "a" , Property_String_a_ .class , String .class , String .class , String .class );
415+ }
416+
417+ interface Property_String_b_ {
418+ ValueFieldReference1 <Property_String_b_ , String , String , String > b =
419+ ValueFieldReference1 .of ( "b" , Property_String_b_ .class , String .class , String .class , String .class );
420+ }
421+
422+ interface Property_Integer_a_ {
423+ ValueFieldReference1 <Property_Integer_a_ , Integer , Integer , Integer > a =
424+ ValueFieldReference1 .of ( "a" , Property_Integer_a_ .class , Integer .class , Integer .class , Integer .class );
425+ }
426+
427+ public static class MappedSuperclassThing_ implements Property_String_a_ {
428+
429+ public static HibernateOrmRootReferenceScope <MappedSuperclassThing_ , MappedSuperclassThing > scope ;
430+
431+ static {
432+ //a = ValueFieldReference1.of( "a", MappedSuperclassThing_.class, String.class, String.class, String.class );
433+
434+ scope = RootReferenceScopeImpl .of ( MappedSuperclassThing_ .class , MappedSuperclassThing .class );
435+ }
436+ }
437+
438+ public static class ContainingA_ extends MappedSuperclassThing_ {
439+ public static e1_ .Absolute e1 ;
440+ public static e2_ .Absolute e2 ;
441+
442+ public static HibernateOrmRootReferenceScope <ContainingA_ , ContainingA > scope ;
443+
444+ static {
445+ e1 = new e1_ .Absolute ();
446+ e2 = new e2_ .Absolute ();
447+
448+ scope = RootReferenceScopeImpl .of ( ContainingA_ .class , ContainingA .class );
449+ }
450+
451+ public static class e1_ implements ObjectFieldReference <ContainingA_ >, Property_String_a_ , Property_String_b_ {
452+
453+ @ Override
454+ public String absolutePath () {
455+ return "e1" ;
456+ }
457+
458+ @ Override
459+ public Class <ContainingA_ > scopeRootType () {
460+ return ContainingA_ .class ;
461+ }
462+
463+ static class Absolute extends e1_ {
464+ public static ValueFieldReference1 <ContainingA_ , String , String , String > a ;
465+ public static ValueFieldReference1 <ContainingA_ , String , String , String > b ;
466+
467+ static {
468+ a = ValueFieldReference1 .of ( "e1.a" , ContainingA_ .class , String .class , String .class , String .class );
469+ b = ValueFieldReference1 .of ( "e1.b" , ContainingA_ .class , String .class , String .class , String .class );
470+ }
471+ }
472+ }
473+
474+ public static class e2_ implements ObjectFieldReference <ContainingA_ >, Property_String_a_ , Property_String_b_ {
475+
476+ @ Override
477+ public String absolutePath () {
478+ return "e2" ;
479+ }
480+
481+ @ Override
482+ public Class <ContainingA_ > scopeRootType () {
483+ return ContainingA_ .class ;
484+ }
485+
486+ static class Absolute extends e2_ {
487+ public static ValueFieldReference1 <ContainingA_ , String , String , String > a ;
488+ public static ValueFieldReference1 <ContainingA_ , String , String , String > b ;
489+
490+ static {
491+ a = ValueFieldReference1 .of ( "e2.a" , ContainingA_ .class , String .class , String .class , String .class );
492+ b = ValueFieldReference1 .of ( "e2.b" , ContainingA_ .class , String .class , String .class , String .class );
493+ }
494+ }
495+ }
496+ }
497+
498+ public static class ContainingB_ extends MappedSuperclassThing_ {
499+ public static e3_ .Absolute e3 ;
500+
501+ public static HibernateOrmRootReferenceScope <ContainingB_ , ContainingB > scope ;
502+
503+ static {
504+ e3 = new e3_ .Absolute ();
505+
506+ scope = RootReferenceScopeImpl .of ( ContainingB_ .class , ContainingB .class );
507+ }
508+
509+ public static class e3_ implements ObjectFieldReference <ContainingB_ >, Property_Integer_a_ {
510+
511+ @ Override
512+ public String absolutePath () {
513+ return "e3" ;
514+ }
515+
516+ @ Override
517+ public Class <ContainingB_ > scopeRootType () {
518+ return ContainingB_ .class ;
519+ }
520+
521+ public static class Absolute extends e3_ {
522+ public static ValueFieldReference1 <ContainingB_ , Integer , Integer , Integer > a ;
523+
524+ static {
525+ a = ValueFieldReference1 .of ( "e3.a" , ContainingB_ .class , Integer .class , Integer .class , Integer .class );
526+ }
527+ }
528+ }
529+ }
530+
531+ public static PredicateFinalStep utilMethodForPredicate (SearchPredicateFactory <? extends Property_String_a_ > factory ) {
532+ return factory .match ().field ( Property_String_a_ .a ).matching ( "a" );
533+ }
534+
335535
336536 public static class ValueFieldReference1 <E , T , V , P > extends TypedFieldReference1 <E , T , P > {
337537
0 commit comments