@Test public void testDefaultNestedJoinFromEntityPath() { JoinerQueryBase<Group, Group> query = Q.from(QGroup.group).joins(J.left(QUser.user1).nested(QStatus.status)); JoinDescription join = query.getJoins().iterator().next().getChildren().iterator().next(); Assert.assertEquals(JoinType.LEFTJOIN, join.getJoinType()); Assert.assertEquals(J.path(QUser.user1, QStatus.status), join.getAlias()); }
@Test public void testInnerJoin() { JoinerQuery<User, User> q = Q.from(QUser.user1).joins(J.inner(QAddress.address)); Assert.assertFalse(joiner.find(q).isEmpty()); q.where(QUser.user1.name.eq("user3")); Assert.assertTrue(joiner.find(q).isEmpty()); }
@Test public void testNestedCollectionAndSingleJoin() { if (noProfiles("eclipse")) { List<Address> addresses = joiner.find(Q.from(QAddress.address)); Assert.assertFalse(Persistence.getPersistenceUtil().isLoaded(addresses.get(0), "user")); Assert.assertFalse( Persistence.getPersistenceUtil().isLoaded(addresses.get(0).getUser(), "groups")); entityManager.clear(); } List<Address> addresses = joiner.find( Q.from(QAddress.address).joins(J.left(QUser.user1).nested(J.left(QGroup.group)))); Assert.assertTrue(Persistence.getPersistenceUtil().isLoaded(addresses.get(0), "user")); Assert.assertTrue( Persistence.getPersistenceUtil().isLoaded(addresses.get(0).getUser(), "groups")); }
@Test public void testRightJoinNoFetch() { if (noProfiles("eclipse")) { List<Group> groups = joiner.find( Q.from(QGroup.group) .joins(J.left(QUser.user1).right().fetch(false)) .where(QUser.user1.name.eq("user1"))); Assert.assertFalse(groups.isEmpty()); } }
@Test public void testNestedCollectionJoin() { List<Group> groups = joiner.find(Q.from(QGroup.group)); Assert.assertFalse(Persistence.getPersistenceUtil().isLoaded(groups.get(0), "users")); Assert.assertFalse( Persistence.getPersistenceUtil() .isLoaded(groups.get(0).getUsers().iterator().next(), "addresses")); entityManager.clear(); groups = joiner.find( Q.from(QGroup.group).joins(J.left(QUser.user1).nested(J.left(QAddress.address)))); Assert.assertTrue(Persistence.getPersistenceUtil().isLoaded(groups.get(0), "users")); Assert.assertTrue( Persistence.getPersistenceUtil() .isLoaded(groups.get(0).getUsers().iterator().next(), "addresses")); }
@Test public void testJoinOn() { String name = "user1"; List<User> groups = joiner.find( Q.select(QUser.user1) .from(QGroup.group) .joins(J.inner(QUser.user1).on(QUser.user1.name.eq(name)).fetch(false))); assertHasName(groups, name); }
@Test public void testNonDistinct() { int nonDistinct = joiner .find( Q.from(QUser.user1) .joins(J.left(QAddress.address).nested(J.left(QStatus.status))) .distinct(false)) .size(); entityManager.clear(); int distinct = joiner.find(Q.from(QUser.user1).joins(J.left(QAddress.address))).size(); if (isEclipse()) { Assert.assertTrue(distinct == nonDistinct); } else { Assert.assertTrue(distinct < nonDistinct); } }
@Test(expected = JoinerException.class) public void testRightJoinNoFetchEclipse() { if (isEclipse()) { List<Group> groups = joiner.find( Q.from(QGroup.group) .joins(J.left(QUser.user1).right().fetch(false)) .where(QUser.user1.name.eq("user1"))); Assert.assertFalse(groups.isEmpty()); } else { throw new JoinerException("Test"); } }
@Test public void noFetchJoinTest() { List<User> users = joiner.find(Q.from(QUser.user1)); Assert.assertFalse(Persistence.getPersistenceUtil().isLoaded(users.get(0), "groups")); JoinDescription e = J.left(QGroup.group).fetch(false); users = joiner.find(Q.from(QUser.user1).joins(Collections.singletonList(e))); Assert.assertFalse(Persistence.getPersistenceUtil().isLoaded(users.get(0), "groups")); e.fetch(true); entityManager.clear(); users = joiner.find(Q.from(QUser.user1).joins(Collections.singletonList(e))); Assert.assertTrue(Persistence.getPersistenceUtil().isLoaded(users.get(0), "groups")); }
private Path<?> findPathOnParent( Path<?> parent, Class<?> targetType, JoinDescription joinDescription) { while (!targetType.equals(Object.class)) { // TODO more efficient cache key String cacheKey = parent.getClass().getName() + parent.toString() + targetType.getSimpleName() + joinDescription.getOriginalAlias().toString(); Path cached = aliasCache.get(cacheKey); if (cached != null && !cached.equals(nullPath)) { // TODO test // TODO optimize inheritance cases return cached; } List<Path<?>> candidatePaths = new ArrayList<>(); for (Field field : parent.getClass().getFields()) { Object candidate = getField(field, parent); testAliasCandidate(targetType, candidatePaths, candidate); } if (candidatePaths.isEmpty()) { for (Class child : ReflectionUtils.getSubclasses(parent.getType(), entityManager)) { Class<?> real; Constructor<?> constructor; try { real = Class.forName( parent.getClass().getPackage().getName() + ".Q" + child.getSimpleName()); constructor = real.getConstructor(String.class); } catch (Exception e) { throw new RuntimeException(); } Object childInstance; try { childInstance = constructor.newInstance(parent.getMetadata().getElement()); } catch (Exception e) { throw new RuntimeException(); } for (Field field : real.getFields()) { Object candidate = getField(field, childInstance); testAliasCandidate(targetType, candidatePaths, candidate); } } } if (candidatePaths.isEmpty()) { // TODO may be exception? J.unrollChildrenJoins(Collections.singletonList(joinDescription)) .forEach(j -> j.fetch(false)); aliasCache.put(cacheKey, nullPath); targetType = targetType.getSuperclass(); } else if (candidatePaths.size() == 1) { aliasCache.put(cacheKey, candidatePaths.get(0)); return candidatePaths.get(0); } else { // Multiple associations on parent, try find by specified alias String targetFieldName = joinDescription.getOriginalAlias().toString(); for (Path<?> candidatePath : candidatePaths) { if (targetFieldName.equals(candidatePath.getMetadata().getElement())) { aliasCache.put(cacheKey, candidatePath); return candidatePath; } } // TODO add candidates to exception throw new JoinerException( "Join with ambiguous alias : " + joinDescription + ". Multiple mappings found: " + candidatePaths); } } return null; }
@Test public void nonCollisionAliasCollectionJoinTest() { joiner.find(Q.from(QGroup.group).joins(J.left(QStatus.status))); }
@Test public void collisionAliasCollectionJoinTest() { joiner.find( Q.from(QGroup.group) .joins(J.left(QStatus.status), J.left(QUser.user1).nested(J.left(QStatus.status)))); }