/** * In a first attempt to implement left joins in Envers, a full join * has been performed and than the entities has been filtered in the * where clause. However, this approach did only work for inner joins * but not for left joins. One of the defects in this approach is, * that audit entities, which have a null 'relatedId' and do match * the query criterias, have been returned multiple times by a query. * This test ensures that this defect is no longer in the current implementation. */ @Test public void testEntitiesWithANullRelatedIdAreNotReturnedMoreThanOnce() { final AuditReader auditReader = getAuditReader(); List<Car> resultList = auditReader.createQuery() .forEntitiesAtRevision( Car.class, 1 ) .traverseRelation( "owner", JoinType.LEFT, "p" ) .up().add( AuditEntity.or( AuditEntity.property( "make" ).eq( "car3" ), AuditEntity.property( "p", "age" ).eq( 10 ) ) ) .getResultList(); assertEquals( "Expected car3 to be returned but only once", 1, resultList.size() ); assertEquals( "Unexpected car at index 0", car3.getId(), resultList.get(0).getId() ); }
@Test public void testLeftJoinOnAuditedEntity() { final AuditReader auditReader = getAuditReader(); // all cars where the owner has an age of 20 or where there is no owner at all List<Car> resultList = auditReader.createQuery() .forEntitiesAtRevision( Car.class, 1 ) .traverseRelation( "owner", JoinType.LEFT, "p" ) .up().add( AuditEntity.or( AuditEntity.property( "p", "age").eq( 20 ), AuditEntity.relatedId( "owner" ).eq( null ) ) ) .addOrder( AuditEntity.property( "make" ).asc() ).getResultList(); assertEquals( "The result list should have 2 results, car1 because its owner has an age of 30 and car3 because it has no owner at all", 2, resultList.size() ); Car car0 = resultList.get(0); Car car1 = resultList.get(1); assertEquals( "Unexpected car at index 0", car2.getId(), car0.getId() ); assertEquals( "Unexpected car at index 0", car3.getId(), car1.getId() ); }
.traverseRelation( "address", JoinType.LEFT, "a" ) .add( AuditEntity.or( AuditEntity.property( "a", "city" ).eq( "Cluj-Napoca" ), AuditEntity.relatedId( "country" ).eq( null )