@Override @SuppressWarnings({"unchecked"}) public List<Number> getRevisions(Class<?> cls, String entityName, Object primaryKey) throws IllegalArgumentException, NotAuditedException, IllegalStateException { // todo: if a class is not versioned from the beginning, there's a missing ADD rev - what then? cls = getTargetClassIfProxied( cls ); checkNotNull( cls, "Entity class" ); checkNotNull( entityName, "Entity name" ); checkNotNull( primaryKey, "Primary key" ); checkSession(); return createQuery().forRevisionsOfEntity( cls, entityName, false, true ) .addProjection( AuditEntity.revisionNumber() ) .addOrder( AuditEntity.revisionNumber().asc() ) .add( AuditEntity.id().eq( primaryKey ) ) .getResultList(); }
@Override protected Object queryForReferencedEntity( AuditReaderImplementor versionsReader, EntityInfo referencedEntity, Serializable primaryKey, Number revision) { return versionsReader.createQuery().forEntitiesAtRevision( referencedEntity.getEntityClass(), referencedEntity.getEntityName(), revision ) .add( AuditEntity.relatedId( owningReferencePropertyName ).eq( primaryKey ) ) .getSingleResult(); } }
@Test public void testEntitiesOrderLimitByQueryRev1() { List res_0_to_1 = getAuditReader().createQuery() .forEntitiesAtRevision( IntTestEntity.class, 1 ) .addOrder( AuditEntity.property( "number" ).desc() ) .setFirstResult( 0 ) .setMaxResults( 2 ) .getResultList(); List res_2_to_3 = getAuditReader().createQuery() .forEntitiesAtRevision( IntTestEntity.class, 1 ) .addOrder( AuditEntity.property( "number" ).desc() ) .setFirstResult( 2 ) .setMaxResults( 2 ) .getResultList(); List res_empty = getAuditReader().createQuery() .forEntitiesAtRevision( IntTestEntity.class, 1 ) .addOrder( AuditEntity.property( "number" ).desc() ) .setFirstResult( 4 ) .setMaxResults( 2 ) .getResultList(); assert Arrays.asList( new IntTestEntity( 12, id1 ), new IntTestEntity( 8, id3 ) ).equals( res_0_to_1 ); assert Arrays.asList( new IntTestEntity( 5, id2 ), new IntTestEntity( 1, id4 ) ).equals( res_2_to_3 ); assert Arrays.asList().equals( res_empty ); }
@Test public void testHasChangedHasNotChangedCriteria() throws Exception { List list = getAuditReader().createQuery().forRevisionsOfEntity( AuditedTestEntity.class, true, true ) .add( AuditEntity.property( "str1" ).hasChanged() ).getResultList(); assertEquals( 2, list.size() ); assertEquals( "str1", ((AuditedTestEntity) list.get( 0 )).getStr1() ); assertEquals( "str2", ((AuditedTestEntity) list.get( 1 )).getStr1() ); list = getAuditReader().createQuery().forRevisionsOfEntity( AuditedTestEntity.class, true, true ) .add( AuditEntity.property( "str1" ).hasNotChanged() ).getResultList(); assertTrue( list.isEmpty() ); }
@Test @TestForIssue(jiraKey = "HHH-8036") public void testEntityIdOrdering() { List<IntTestEntity> list = getAuditReader().createQuery().forRevisionsOfEntity( IntTestEntity.class, true, true ) .add( AuditEntity.revisionNumber().lt( 2 ) ) .addOrder( AuditEntity.id().desc() ) .getResultList(); Assert.assertEquals( Arrays.asList( new IntTestEntity( 10, 2 ), new IntTestEntity( 2, 1 ) ), list ); }
@Test @FailureExpected(jiraKey = "HHH-11841", message = "Reverted fix in HHH-12018 and will be fixed in HHH-12043") public void testRevisionHistory() { final AuditReader reader = getAuditReader(); AuditQuery categoryQuery = reader.createQuery().forRevisionsOfEntity( Category.class, false, true ) .addOrder( AuditEntity.revisionProperty( "timestamp" ).asc() ) .add( AuditEntity.id().eq( category.getId() ) ); @SuppressWarnings( "unchecked" ) List<Object[]> history = (List<Object[]>) categoryQuery.getResultList(); assertNotNull( history ); assertEquals( 1, history.size() ); final Category category = (Category) reader.createQuery().forEntitiesAtRevision( Category.class, 1 ) .add( AuditEntity.property( "id" ).eq( this.category.getId() ) ) .setMaxResults( 1 ) .getSingleResult(); assertEquals( this.category.getName(), category.getName() ); assertEquals( this.category.getDescription(), category.getDescription() ); assertEquals( "The text", category.getText( this.item ) ); final Value value = category.getValue( this.item ); assertEquals( "The Value", value.getText() ); assertEquals( Long.valueOf( 4711L ), value.getNumberValue() ); }
@Test public void testRevisionsLeWithPropertyQuery() { List result = getAuditReader().createQuery() .forRevisionsOfEntity( StrIntTestEntity.class, false, true ) .addProjection( AuditEntity.revisionNumber() ) .add( AuditEntity.revisionNumber().le( 3 ) ) .add( AuditEntity.property( "str1" ).eq( "a" ) ) .getResultList(); Assert.assertEquals( Arrays.asList( 1 ), result ); }
@Test public void testEntitiesRemovedAtRevision() { StrIntTestEntity site1 = new StrIntTestEntity( null, null, id1 ); List result = getAuditReader().createQuery() .forEntitiesModifiedAtRevision( StrIntTestEntity.class, 4 ) .getResultList(); RevisionType revisionType = (RevisionType) getAuditReader().createQuery().forEntitiesModifiedAtRevision( StrIntTestEntity.class, 4 ) .addProjection( AuditEntity.revisionType() ).add( AuditEntity.id().eq( id1 ) ) .getSingleResult(); Assert.assertTrue( TestTools.checkCollection( result, site1 ) ); Assert.assertEquals( revisionType, RevisionType.DEL ); }
.createQuery() .forEntitiesAtRevision( Customer.class, revisions.get( 0 ) ) .getSingleResult(); .createQuery() .forRevisionsOfEntity( Customer.class, true, true ) .add( AuditEntity.property( "firstName" ).eq( "John" ) ) .getResultList(); .createQuery() .forRevisionsOfEntity( Customer.class, true, true ) .add( AuditEntity.property( "address" ).eq( address ) ) .getResultList(); .createQuery() .forRevisionsOfEntity( Customer.class, true, true ) .add( AuditEntity.relatedId( "address" ).eq( 1L ) ) .getResultList(); .createQuery() .forRevisionsOfEntity( Customer.class, true, true ) .add( AuditEntity.relatedId( "address" ).in( new Object[] { 1L, 2L } ) ) .getResultList(); .createQuery() .forRevisionsOfEntity( Customer.class, true, true ) .addOrder( AuditEntity.property( "lastName" ).desc() ) .add( AuditEntity.relatedId( "address" ).eq( 1L ) ) .setFirstResult( 1 )
@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() ); }
@Test public void testRevisionCountQuery() { // The query shouldn't be ordered as always, otherwise - we get an exception. Object result = getAuditReader().createQuery() .forRevisionsOfEntity( StrIntTestEntity.class, false, true ) .addProjection( AuditEntity.revisionNumber().count() ) .add( AuditEntity.id().eq( id1 ) ) .getSingleResult(); Assert.assertEquals( Long.valueOf( 4 ), result ); }
@Test public void testEntitiesReferencedByIng1ToId3() { List rev1_related = getAuditReader().createQuery() .forEntitiesAtRevision( SetRefIngEmbIdEntity.class, 1 ) .add( AuditEntity.relatedId( "reference" ).eq( id3 ) ) .add( AuditEntity.id().eq( id1 ) ) .getResultList(); Object rev2_related = getAuditReader().createQuery() .forEntitiesAtRevision( SetRefIngEmbIdEntity.class, 2 ) .add( AuditEntity.relatedId( "reference" ).eq( id3 ) ) .add( AuditEntity.id().eq( id1 ) ) .getSingleResult(); Object rev3_related = getAuditReader().createQuery() .forEntitiesAtRevision( SetRefIngEmbIdEntity.class, 3 ) .add( AuditEntity.relatedId( "reference" ).eq( id3 ) ) .add( AuditEntity.id().eq( id1 ) ) .getSingleResult(); assert rev1_related.size() == 0; assert rev2_related.equals( new SetRefIngEmbIdEntity( id1, "x", null ) ); assert rev3_related.equals( new SetRefIngEmbIdEntity( id1, "x", null ) ); }
@Test public void testAssociationQuery() { final AuditReader auditReader = getAuditReader(); final Car result1 = (Car) auditReader.createQuery().forEntitiesAtRevision( Car.class, 1 ).traverseRelation( "owner", JoinType.INNER ) .add( AuditEntity.property( "name" ).like( "Ford%" ) ).getSingleResult(); assertEquals( "Unexpected single car at revision 1", ford.getId(), result1.getId() ); Car result2 = (Car) auditReader.createQuery().forEntitiesAtRevision( Car.class, 1 ).traverseRelation( "owner", JoinType.INNER ).traverseRelation( "address", JoinType.INNER ) .add( AuditEntity.property( "number" ).eq( 30 ) ).getSingleResult(); assertEquals( "Unexpected single car at revision 1", toyota.getId(), result2.getId() ); List<Car> resultList1 = auditReader.createQuery().forEntitiesAtRevision( Car.class, 1 ).traverseRelation( "owner", JoinType.INNER ) .add( AuditEntity.property( "age" ).ge( 30 ) ).add( AuditEntity.property( "age" ).lt( 40 ) ).up() .addOrder( AuditEntity.property( "make" ).asc() ).getResultList(); assertEquals( "Unexpected number of cars for query in revision 1", 2, resultList1.size() ); assertEquals( "Unexpected car at index 0 in revision 1", ford.getId(), resultList1.get( 0 ).getId() ); assertEquals( "Unexpected car at index 1 in revision 2", toyota.getId(), resultList1.get( 1 ).getId() ); Car result3 = (Car) auditReader.createQuery().forEntitiesAtRevision( Car.class, 2 ).traverseRelation( "owner", JoinType.INNER ) .add( AuditEntity.property( "age" ).ge( 30 ) ).add( AuditEntity.property( "age" ).lt( 40 ) ).up() .addOrder( AuditEntity.property( "make" ).asc() ).getSingleResult(); assertEquals( "Unexpected car at revision 2", ford.getId(), result3.getId() ); }
@Test public void testPolymorphicQuery() { ParentEntity parentVer1 = new ParentEntity( id1, "x" ); assert getAuditReader().createQuery().forEntitiesAtRevision( ParentEntity.class, 1 ).getSingleResult() .equals( parentVer1 ); assert getAuditReader().createQuery().forEntitiesAtRevision( ChildEntity.class, 1 ) .getResultList().size() == 0; } }
@Test public void testComparisonOfTwoPropertiesFromDifferentEntities() { AuditReader auditReader = getAuditReader(); // the car where the owner age is equal to the owner address number. Car result = (Car) auditReader.createQuery() .forEntitiesAtRevision( Car.class, 1 ) .traverseRelation( "owner", JoinType.INNER, "p" ) .traverseRelation( "address", JoinType.INNER, "a" ) .up().up().add(AuditEntity.property( "p", "age" ) .eqProperty( "a", "number" ) ).getSingleResult(); assertEquals( "Unexpected car returned", toyota.getId(), result.getId() ); }
@Test public void testProjectionsInEntitiesAtRevision() { assert getAuditReader().createQuery().forEntitiesAtRevision( StrIntTestEntity.class, 1 ) .getResultList().size() == 2; assert getAuditReader().createQuery().forEntitiesAtRevision( StrIntTestEntity.class, 2 ) .getResultList().size() == 1; assert (Long) getAuditReader().createQuery().forEntitiesAtRevision( StrIntTestEntity.class, 1 ) .addProjection( AuditEntity.id().count() ).getResultList().get( 0 ) == 2; assert (Long) getAuditReader().createQuery().forEntitiesAtRevision( StrIntTestEntity.class, 2 ) .addProjection( AuditEntity.id().count() ).getResultList().get( 0 ) == 1; }
@Test public void testEntitiesAvgMaxQuery() { Object[] ver1 = (Object[]) getAuditReader().createQuery() .forEntitiesAtRevision( IntTestEntity.class, 1 ) .addProjection( AuditEntity.property( "number" ).max() ) .addProjection( AuditEntity.property( "number" ).function( "avg" ) ) .getSingleResult(); Object[] ver2 = (Object[]) getAuditReader().createQuery() .forEntitiesAtRevision( IntTestEntity.class, 2 ) .addProjection( AuditEntity.property( "number" ).max() ) .addProjection( AuditEntity.property( "number" ).function( "avg" ) ) .getSingleResult(); Object[] ver3 = (Object[]) getAuditReader().createQuery() .forEntitiesAtRevision( IntTestEntity.class, 3 ) .addProjection( AuditEntity.property( "number" ).max() ) .addProjection( AuditEntity.property( "number" ).function( "avg" ) ) .getSingleResult(); assert (Integer) ver1[0] == 10; assert (Double) ver1[1] == 6.0; assert (Integer) ver2[0] == 10; assert (Double) ver2[1] == 6.0; assert (Integer) ver3[0] == 52; assert (Double) ver3[1] == 20.0; }
public ResourceContextEntity getResourceContextEntityForPropertyOnMasterResource(AuditViewEntryContainer container) { try { Query query = entityManager .createNativeQuery(SELECT_FOR_PROP_ON_RESOURCE) .setParameter("rev", container.getRevEntity().getId()) .setParameter("propertyId", container.getEntityForRevision().getId()); BigDecimal resourceContextId = (BigDecimal) query.getSingleResult(); AuditReader reader = AuditReaderFactory.get(entityManager); return (ResourceContextEntity) reader.createQuery() .forRevisionsOfEntity(ResourceContextEntity.class, true, true) .add(AuditEntity.id().eq(resourceContextId.intValue())) .setMaxResults(1) .getSingleResult(); } catch (NoResultException e) { return null; } } }
protected List queryForPropertyHasChangedWithDeleted( Class<?> clazz, Object id, String... propertyNames) { AuditQuery query = createForRevisionsQuery( clazz, id, true ); addHasChangedProperties( query, propertyNames ); return query.getResultList(); }
@Test public void testPolymorphicQuery() { ChildEntity childVer1 = new ChildEntity( id1, "x", null ); assert getAuditReader().createQuery().forEntitiesAtRevision( ChildEntity.class, 1 ).getSingleResult() .equals( childVer1 ); assert getAuditReader().createQuery().forEntitiesAtRevision( ParentEntity.class, 1 ).getSingleResult() .equals( childVer1 ); } }