@@ -264,6 +264,67 @@ void referencesCollectionViaJoin() {
264264 "SELECT r FROM JpqlQueryBuilderUnitTests$Race r LEFT JOIN r.lineup l WHERE l.groups IS NOT EMPTY" );
265265 }
266266
267+ @ Test // GH-4110
268+ void referencesCollectionViaMultipleJoins () {
269+
270+ TestMetaModel model = TestMetaModel .hibernateModel (TestUser .class , TestRole .class );
271+ Entity entity = entity (TestUser .class );
272+
273+ EntityType <TestUser > entityType = model .entity (TestUser .class );
274+ JpqlQueryBuilder .PathExpression pas = JpqlUtils .toExpressionRecursively (model , entity , entityType ,
275+ PropertyPath .from ("manager.colleagues.roles" , TestUser .class ));
276+ String jpql = JpqlQueryBuilder .selectFrom (entity ).entity ().where (JpqlQueryBuilder .where (pas ).isEmpty ()).render ();
277+
278+ assertThat (jpql ).isEqualTo (
279+ "SELECT t FROM JpqlQueryBuilderUnitTests$TestUser t LEFT JOIN t.manager m LEFT JOIN m.colleagues c WHERE c.roles IS EMPTY" );
280+ }
281+
282+ @ Test // GH-4110
283+ void referencesCollectionViaJoinWithMemberOf () {
284+
285+ TestMetaModel model = TestMetaModel .hibernateModel (TestUser .class , TestRole .class );
286+ Entity entity = entity (TestUser .class );
287+
288+ EntityType <TestUser > entityType = model .entity (TestUser .class );
289+ JpqlQueryBuilder .PathExpression pas = JpqlUtils .toExpressionRecursively (model , entity , entityType ,
290+ PropertyPath .from ("colleagues.roles" , TestUser .class ));
291+ String jpql = JpqlQueryBuilder .selectFrom (entity ).entity ()
292+ .where (JpqlQueryBuilder .where (pas ).memberOf (JpqlQueryBuilder .parameter ("?1" ))).render ();
293+
294+ assertThat (jpql ).isEqualTo (
295+ "SELECT t FROM JpqlQueryBuilderUnitTests$TestUser t LEFT JOIN t.colleagues c WHERE ?1 MEMBER OF c.roles" );
296+ }
297+
298+ @ Test // GH-4110
299+ void directCollectionPropertyDoesNotCreateJoin () {
300+
301+ TestMetaModel model = TestMetaModel .hibernateModel (TestUser .class , TestRole .class );
302+ Entity entity = entity (TestUser .class );
303+
304+ EntityType <TestUser > entityType = model .entity (TestUser .class );
305+ JpqlQueryBuilder .PathExpression pas = JpqlUtils .toExpressionRecursively (model , entity , entityType ,
306+ PropertyPath .from ("roles" , TestUser .class ));
307+ String jpql = JpqlQueryBuilder .selectFrom (entity ).entity ().where (JpqlQueryBuilder .where (pas ).isEmpty ()).render ();
308+
309+ assertThat (jpql ).isEqualTo ("SELECT t FROM JpqlQueryBuilderUnitTests$TestUser t WHERE t.roles IS EMPTY" );
310+ }
311+
312+ @ Test // GH-4110
313+ void collectionWithAdditionalPathSegments () {
314+
315+ TestMetaModel model = TestMetaModel .hibernateModel (TestUser .class , TestRole .class );
316+ Entity entity = entity (TestUser .class );
317+
318+ EntityType <TestUser > entityType = model .entity (TestUser .class );
319+ JpqlQueryBuilder .PathExpression pas = JpqlUtils .toExpressionRecursively (model , entity , entityType ,
320+ PropertyPath .from ("colleagues.roles.name" , TestUser .class ));
321+ String jpql = JpqlQueryBuilder .selectFrom (entity ).entity ()
322+ .where (JpqlQueryBuilder .where (pas ).eq (literal ("ADMIN" ))).render ();
323+
324+ assertThat (jpql ).isEqualTo (
325+ "SELECT t FROM JpqlQueryBuilderUnitTests$TestUser t LEFT JOIN t.colleagues c LEFT JOIN c.roles r WHERE r.name = 'ADMIN'" );
326+ }
327+
267328 static ContextualAssert contextual (RenderContext context ) {
268329 return new ContextualAssert (context );
269330 }
@@ -385,4 +446,20 @@ static class GroupId {
385446
386447 }
387448
449+ @ jakarta .persistence .Entity
450+ static class TestUser {
451+
452+ @ Id long id ;
453+ @ ManyToOne TestUser manager ;
454+ @ OneToMany Set <TestUser > colleagues = new HashSet <>();
455+ @ OneToMany Set <TestRole > roles = new HashSet <>();
456+ }
457+
458+ @ jakarta .persistence .Entity
459+ static class TestRole {
460+
461+ @ Id long id ;
462+ String name ;
463+ }
464+
388465}
0 commit comments