HHH-8058 - Enable querying entity revisions with property change indicators.
(backport from wip/6.0)
This commit is contained in:
parent
79354bab9f
commit
664c652a25
|
@ -173,6 +173,7 @@ public class AuditQueryCreator {
|
|||
c,
|
||||
selectEntitiesOnly,
|
||||
selectDeletedEntities,
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
@ -214,6 +215,7 @@ public class AuditQueryCreator {
|
|||
entityName,
|
||||
selectEntitiesOnly,
|
||||
selectDeletedEntities,
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
@ -239,7 +241,8 @@ public class AuditQueryCreator {
|
|||
clazz,
|
||||
false,
|
||||
selectDeletedEntities,
|
||||
true
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -266,6 +269,75 @@ public class AuditQueryCreator {
|
|||
entityName,
|
||||
false,
|
||||
selectDeletedEntities,
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a query that selects the revisions at which the given entity was modified. Unless a
|
||||
* projection is set, the result will be a list of 4-element arrays, containing the following:
|
||||
* <ol>
|
||||
* <li>The entity instance</li>
|
||||
* <li>Revision entity, corresponding to the revision where the entity was modified. If no custom
|
||||
* revision entity is used, this will be an instance of {@link org.hibernate.envers.DefaultRevisionEntity}.</li>
|
||||
* <li>The revision type, an enum of class {@link org.hibernate.envers.RevisionType}.</li>
|
||||
* <li>The names of the properties changed in this revision</li>
|
||||
* </ol>
|
||||
* Additional criterion may be specified to filter the result set.
|
||||
*
|
||||
* @param clazz Class of the entities for which to query.
|
||||
* @param selectDeletedEntities If true, the result set will include revisions where entities were deleted.
|
||||
*
|
||||
* @return the audit query
|
||||
*
|
||||
* @since 5.3
|
||||
*/
|
||||
@Incubating
|
||||
public AuditQuery forRevisionsOfEntityWithChanges(Class<?> clazz, boolean selectDeletedEntities) {
|
||||
clazz = getTargetClassIfProxied( clazz );
|
||||
return new RevisionsOfEntityQuery(
|
||||
enversService,
|
||||
auditReaderImplementor,
|
||||
clazz,
|
||||
false,
|
||||
selectDeletedEntities,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a query that selects the revisions at which the given entity was modified. Unless a
|
||||
* projection is set, the result will be a list of 4-element arrays, containing the following:
|
||||
* <ol>
|
||||
* <li>The entity instance</li>
|
||||
* <li>Revision entity, corresponding to the revision where the entity was modified. If no custom
|
||||
* revision entity is used, this will be an instance of {@link org.hibernate.envers.DefaultRevisionEntity}.</li>
|
||||
* <li>The revision type, an enum of class {@link org.hibernate.envers.RevisionType}.</li>
|
||||
* <li>The names of the properties changed in this revision</li>
|
||||
* </ol>
|
||||
* Additional criterion may be specified to filter the result set.
|
||||
*
|
||||
* @param clazz Class of the entities for which to query.
|
||||
* @param entityName Name of the entity (if it can't be guessed basing on the {@code clazz}).
|
||||
* @param selectDeletedEntities If true, the result set will include revisions where entities were deleted.
|
||||
*
|
||||
* @return the audit query
|
||||
*
|
||||
* @since 5.3
|
||||
*/
|
||||
@Incubating
|
||||
public AuditQuery forRevisionsOfEntityWithChanges(Class<?> clazz, String entityName, boolean selectDeletedEntities) {
|
||||
clazz = getTargetClassIfProxied( clazz );
|
||||
return new RevisionsOfEntityQuery(
|
||||
enversService,
|
||||
auditReaderImplementor,
|
||||
clazz,
|
||||
entityName,
|
||||
false,
|
||||
selectDeletedEntities,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.LockOptions;
|
|||
import org.hibernate.envers.boot.internal.EnversService;
|
||||
import org.hibernate.envers.exception.AuditException;
|
||||
import org.hibernate.envers.exception.NotAuditedException;
|
||||
import org.hibernate.envers.internal.entities.EntityConfiguration;
|
||||
import org.hibernate.envers.internal.entities.EntityInstantiator;
|
||||
import org.hibernate.envers.internal.reader.AuditReaderImplementor;
|
||||
import org.hibernate.envers.internal.tools.query.QueryBuilder;
|
||||
|
@ -341,4 +342,13 @@ public abstract class AbstractAuditQuery implements AuditQueryImplementor {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected EntityConfiguration getEntityConfiguration() {
|
||||
return enversService.getEntitiesConfigurations().get( entityName );
|
||||
}
|
||||
|
||||
protected String getEntityName() {
|
||||
// todo: can this be replaced by a call to getEntittyConfiguration#getEntityClassName()?
|
||||
return entityName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
package org.hibernate.envers.query.internal.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.criteria.JoinType;
|
||||
|
@ -17,6 +20,8 @@ import org.hibernate.envers.RevisionType;
|
|||
import org.hibernate.envers.boot.internal.EnversService;
|
||||
import org.hibernate.envers.configuration.internal.AuditEntitiesConfiguration;
|
||||
import org.hibernate.envers.exception.AuditException;
|
||||
import org.hibernate.envers.internal.entities.PropertyData;
|
||||
import org.hibernate.envers.internal.entities.mapper.ExtendedPropertyMapper;
|
||||
import org.hibernate.envers.internal.entities.mapper.relation.query.QueryConstants;
|
||||
import org.hibernate.envers.internal.reader.AuditReaderImplementor;
|
||||
import org.hibernate.envers.query.AuditAssociationQuery;
|
||||
|
@ -32,6 +37,7 @@ public class RevisionsOfEntityQuery extends AbstractAuditQuery {
|
|||
private final boolean selectEntitiesOnly;
|
||||
private final boolean selectDeletedEntities;
|
||||
private final boolean selectRevisionInfoOnly;
|
||||
private final boolean includePropertyChanges;
|
||||
|
||||
public RevisionsOfEntityQuery(
|
||||
EnversService enversService,
|
||||
|
@ -39,12 +45,14 @@ public class RevisionsOfEntityQuery extends AbstractAuditQuery {
|
|||
Class<?> cls,
|
||||
boolean selectEntitiesOnly,
|
||||
boolean selectDeletedEntities,
|
||||
boolean selectRevisionInfoOnly) {
|
||||
boolean selectRevisionInfoOnly,
|
||||
boolean includePropertyChanges) {
|
||||
super( enversService, versionsReader, cls );
|
||||
|
||||
this.selectEntitiesOnly = selectEntitiesOnly;
|
||||
this.selectDeletedEntities = selectDeletedEntities;
|
||||
this.selectRevisionInfoOnly = selectRevisionInfoOnly && !selectEntitiesOnly;
|
||||
this.includePropertyChanges = includePropertyChanges;
|
||||
}
|
||||
|
||||
public RevisionsOfEntityQuery(
|
||||
|
@ -53,12 +61,14 @@ public class RevisionsOfEntityQuery extends AbstractAuditQuery {
|
|||
Class<?> cls, String entityName,
|
||||
boolean selectEntitiesOnly,
|
||||
boolean selectDeletedEntities,
|
||||
boolean selectRevisionInfoOnly) {
|
||||
boolean selectRevisionInfoOnly,
|
||||
boolean includePropertyChanges) {
|
||||
super( enversService, versionsReader, cls, entityName );
|
||||
|
||||
this.selectEntitiesOnly = selectEntitiesOnly;
|
||||
this.selectDeletedEntities = selectDeletedEntities;
|
||||
this.selectRevisionInfoOnly = selectRevisionInfoOnly && !selectEntitiesOnly;
|
||||
this.includePropertyChanges = includePropertyChanges;
|
||||
}
|
||||
|
||||
private Number getRevisionNumber(Map versionsEntity) {
|
||||
|
@ -123,49 +133,7 @@ public class RevisionsOfEntityQuery extends AbstractAuditQuery {
|
|||
);
|
||||
}
|
||||
|
||||
List<Object> queryResult = buildAndExecuteQuery();
|
||||
if ( hasProjection() ) {
|
||||
return queryResult;
|
||||
}
|
||||
else if ( selectRevisionInfoOnly ) {
|
||||
return queryResult.stream().map( e -> ( (Object[]) e )[1] ).collect( Collectors.toList() );
|
||||
}
|
||||
else {
|
||||
List entities = new ArrayList();
|
||||
String revisionTypePropertyName = verEntCfg.getRevisionTypePropName();
|
||||
|
||||
for ( Object resultRow : queryResult ) {
|
||||
Map versionsEntity;
|
||||
Object revisionData;
|
||||
|
||||
if ( selectEntitiesOnly ) {
|
||||
versionsEntity = (Map) resultRow;
|
||||
revisionData = null;
|
||||
}
|
||||
else {
|
||||
Object[] arrayResultRow = (Object[]) resultRow;
|
||||
versionsEntity = (Map) arrayResultRow[0];
|
||||
revisionData = arrayResultRow[1];
|
||||
}
|
||||
|
||||
Number revision = getRevisionNumber( versionsEntity );
|
||||
|
||||
Object entity = entityInstantiator.createInstanceFromVersionsEntity(
|
||||
entityName,
|
||||
versionsEntity,
|
||||
revision
|
||||
);
|
||||
|
||||
if ( !selectEntitiesOnly ) {
|
||||
entities.add( new Object[] {entity, revisionData, versionsEntity.get( revisionTypePropertyName )} );
|
||||
}
|
||||
else {
|
||||
entities.add( entity );
|
||||
}
|
||||
}
|
||||
|
||||
return entities;
|
||||
}
|
||||
return getQueryResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -173,4 +141,87 @@ public class RevisionsOfEntityQuery extends AbstractAuditQuery {
|
|||
throw new UnsupportedOperationException( "Not yet implemented for revisions of entity queries" );
|
||||
}
|
||||
|
||||
private boolean isEntityUsingModifiedFlags() {
|
||||
// todo: merge HHH-8973 ModifiedFlagMapperSupport into 6.0 to get this behavior by default
|
||||
final ExtendedPropertyMapper propertyMapper = getEntityConfiguration().getPropertyMapper();
|
||||
for ( PropertyData propertyData : propertyMapper.getProperties().keySet() ) {
|
||||
if ( propertyData.isUsingModifiedFlag() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Set<String> getChangedPropertyNames(Map<String, Object> dataMap, Object revisionType) {
|
||||
final Set<String> changedPropertyNames = new HashSet<>();
|
||||
// we're only interested in changed properties on modification rows.
|
||||
if ( revisionType == RevisionType.MOD ) {
|
||||
final String modifiedFlagSuffix = enversService.getGlobalConfiguration().getModifiedFlagSuffix();
|
||||
for ( Map.Entry<String, Object> entry : dataMap.entrySet() ) {
|
||||
final String key = entry.getKey();
|
||||
if ( key.endsWith( modifiedFlagSuffix ) ) {
|
||||
if ( entry.getValue() != null && Boolean.parseBoolean( entry.getValue().toString() ) ) {
|
||||
changedPropertyNames.add( key.substring( 0, key.length() - modifiedFlagSuffix.length() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return changedPropertyNames;
|
||||
}
|
||||
|
||||
private List getQueryResults() {
|
||||
List<?> queryResults = buildAndExecuteQuery();
|
||||
if ( hasProjection() ) {
|
||||
return queryResults;
|
||||
}
|
||||
else if ( selectRevisionInfoOnly ) {
|
||||
return queryResults.stream().map( e -> ( (Object[]) e )[1] ).collect( Collectors.toList() );
|
||||
}
|
||||
else {
|
||||
List entities = new ArrayList();
|
||||
if ( selectEntitiesOnly ) {
|
||||
for ( Object row : queryResults ) {
|
||||
final Map versionsEntity = (Map) row;
|
||||
entities.add( getQueryResultRowValue( versionsEntity, null, getEntityName() ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
for ( Object row : queryResults ) {
|
||||
final Object[] rowArray = (Object[]) row;
|
||||
final Map versionsEntity = (Map) rowArray[ 0 ];
|
||||
final Object revisionData = rowArray[ 1 ];
|
||||
entities.add( getQueryResultRowValue( versionsEntity, revisionData, getEntityName() ) );
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
|
||||
private Object getQueryResultRowValue(Map versionsData, Object revisionData, String entityName) {
|
||||
final Number revision = getRevisionNumber( versionsData );
|
||||
|
||||
final Object entity = entityInstantiator.createInstanceFromVersionsEntity( entityName, versionsData, revision );
|
||||
if ( selectEntitiesOnly ) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
final String revisionTypePropertyName = enversService.getAuditEntitiesConfiguration().getRevisionTypePropName();
|
||||
Object revisionType = versionsData.get( revisionTypePropertyName );
|
||||
if ( !includePropertyChanges ) {
|
||||
return new Object[] { entity, revisionData, revisionType };
|
||||
}
|
||||
|
||||
if ( !isEntityUsingModifiedFlags() ) {
|
||||
throw new AuditException(
|
||||
String.format(
|
||||
Locale.ROOT,
|
||||
"The specified entity [%s] does not support or use modified flags.",
|
||||
getEntityConfiguration().getEntityClassName()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
final Set<String> changedPropertyNames = getChangedPropertyNames( versionsData, revisionType );
|
||||
return new Object[] { entity, revisionData, revisionType, changedPropertyNames };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.envers.test.integration.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.hibernate.envers.Audited;
|
||||
import org.hibernate.envers.RevisionType;
|
||||
import org.hibernate.envers.configuration.EnversSettings;
|
||||
import org.hibernate.envers.query.AuditEntity;
|
||||
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||
import org.hibernate.envers.test.Priority;
|
||||
import org.hibernate.envers.test.tools.TestTools;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-8058" )
|
||||
public abstract class AbstractEntityWithChangesQueryTest extends BaseEnversJPAFunctionalTestCase {
|
||||
private Integer simpleId;
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Simple.class };
|
||||
}
|
||||
|
||||
@Test
|
||||
@Priority(10)
|
||||
public void initData() {
|
||||
// Revision 1
|
||||
simpleId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Simple simple = new Simple();
|
||||
simple.setName( "Name" );
|
||||
simple.setValue( 25 );
|
||||
entityManager.persist( simple );
|
||||
return simple.getId();
|
||||
} );
|
||||
|
||||
// Revision 2
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Simple simple = entityManager.find( Simple.class, simpleId );
|
||||
simple.setName( "Name-Modified2" );
|
||||
entityManager.merge( simple );
|
||||
} );
|
||||
|
||||
// Revision 3
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Simple simple = entityManager.find( Simple.class, simpleId );
|
||||
simple.setName( "Name-Modified3" );
|
||||
simple.setValue( 100 );
|
||||
entityManager.merge( simple );
|
||||
} );
|
||||
|
||||
// Revision 4
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Simple simple = entityManager.find( Simple.class, simpleId );
|
||||
entityManager.remove( simple );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevisionCount() {
|
||||
assertEquals( Arrays.asList( 1, 2, 3, 4 ), getAuditReader().getRevisions( Simple.class, simpleId ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntityRevisionsWithChangesQueryNoDeletions() {
|
||||
List results = getAuditReader().createQuery()
|
||||
.forRevisionsOfEntityWithChanges( Simple.class, false )
|
||||
.add( AuditEntity.id().eq( simpleId ) )
|
||||
.getResultList();
|
||||
compareResults( getExpectedResults( false ), results );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntityRevisionsWithChangesQuery() {
|
||||
List results = getAuditReader().createQuery()
|
||||
.forRevisionsOfEntityWithChanges( Simple.class, true )
|
||||
.add( AuditEntity.id().eq( simpleId ) )
|
||||
.getResultList();
|
||||
compareResults( getExpectedResults( true ), results );
|
||||
}
|
||||
|
||||
private void compareResults(List<Object[]> expectedResults, List results) {
|
||||
assertEquals( expectedResults.size(), results.size() );
|
||||
for ( int i = 0; i < results.size(); ++i ) {
|
||||
final Object[] row = (Object[]) results.get( i );
|
||||
final Object[] expectedRow = expectedResults.get( i );
|
||||
// the query returns 4, index 1 has the revision entity which we don't test here
|
||||
assertEquals( 4, row.length );
|
||||
// because we don't test the revision entity, we adjust indexes between the two arrays
|
||||
assertEquals( expectedRow[ 0 ], row[ 0 ] );
|
||||
assertEquals( expectedRow[ 1 ], row[ 2 ] );
|
||||
assertEquals( expectedRow[ 2 ], row[ 3 ] );
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Object[]> getExpectedResults(boolean includeDeletions) {
|
||||
|
||||
String deleteName = null;
|
||||
Integer deleteValue = null;
|
||||
if ( getConfig().get( EnversSettings.STORE_DATA_AT_DELETE ) == Boolean.TRUE ) {
|
||||
deleteName = "Name-Modified3";
|
||||
deleteValue = 100;
|
||||
}
|
||||
|
||||
final List<Object[]> results = new ArrayList<>();
|
||||
|
||||
results.add(
|
||||
new Object[] {
|
||||
new Simple( simpleId, "Name", 25 ),
|
||||
RevisionType.ADD,
|
||||
Collections.emptySet()
|
||||
}
|
||||
);
|
||||
|
||||
results.add(
|
||||
new Object[] {
|
||||
new Simple( simpleId, "Name-Modified2", 25 ),
|
||||
RevisionType.MOD,
|
||||
TestTools.makeSet( "name" )
|
||||
}
|
||||
);
|
||||
|
||||
results.add(
|
||||
new Object[] {
|
||||
new Simple( simpleId, "Name-Modified3", 100 ),
|
||||
RevisionType.MOD,
|
||||
TestTools.makeSet( "name", "value" )
|
||||
}
|
||||
);
|
||||
|
||||
if ( includeDeletions ) {
|
||||
results.add(
|
||||
new Object[] {
|
||||
new Simple( simpleId, deleteName, deleteValue ),
|
||||
RevisionType.DEL,
|
||||
Collections.emptySet()
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
System.out.println( "Generated " + results.size() + " results." );
|
||||
return results;
|
||||
}
|
||||
|
||||
@Audited
|
||||
@Entity(name = "Simple")
|
||||
public static class Simple {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
private String name;
|
||||
private Integer value;
|
||||
|
||||
Simple() {
|
||||
|
||||
}
|
||||
|
||||
Simple(Integer id, String name, Integer value) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Simple simple = (Simple) o;
|
||||
|
||||
if ( getId() != null ? !getId().equals( simple.getId() ) : simple.getId() != null ) {
|
||||
return false;
|
||||
}
|
||||
if ( getName() != null ? !getName().equals( simple.getName() ) : simple.getName() != null ) {
|
||||
return false;
|
||||
}
|
||||
return getValue() != null ? getValue().equals( simple.getValue() ) : simple.getValue() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = getId() != null ? getId().hashCode() : 0;
|
||||
result = 31 * result + ( getName() != null ? getName().hashCode() : 0 );
|
||||
result = 31 * result + ( getValue() != null ? getValue().hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Simple{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
", value=" + value +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.envers.test.integration.query;
|
||||
|
||||
import org.hibernate.envers.exception.AuditException;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-8058" )
|
||||
public class EntityWithChangesQueryNoModifiedFlagTest extends AbstractEntityWithChangesQueryTest {
|
||||
@Test
|
||||
public void testEntityRevisionsWithChangesQueryNoDeletions() {
|
||||
try {
|
||||
super.testEntityRevisionsWithChangesQueryNoDeletions();
|
||||
fail( "This should have failed with AuditException since test case doesn't enable modifiedFlag" );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
assertTyping( AuditException.class, e );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntityRevisionsWithChangesQuery() {
|
||||
try {
|
||||
super.testEntityRevisionsWithChangesQuery();
|
||||
fail( "This should have failed with AuditException since test case doesn't enable modifiedFlag" );
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
assertTyping( AuditException.class, e );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.envers.test.integration.query;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.envers.configuration.EnversSettings;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-8058" )
|
||||
public class EntityWithChangesQueryStoreDeletionDataTest extends AbstractEntityWithChangesQueryTest {
|
||||
@Override
|
||||
protected void addConfigOptions(Map options) {
|
||||
options.put( EnversSettings.GLOBAL_WITH_MODIFIED_FLAG, Boolean.TRUE );
|
||||
options.put( EnversSettings.STORE_DATA_AT_DELETE, Boolean.TRUE );
|
||||
super.addConfigOptions( options );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.envers.test.integration.query;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.envers.configuration.EnversSettings;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue( jiraKey = "HHH-8058" )
|
||||
public class EntityWithChangesQueryTest extends AbstractEntityWithChangesQueryTest {
|
||||
@Override
|
||||
protected void addConfigOptions(Map options) {
|
||||
super.addConfigOptions( options );
|
||||
options.put( EnversSettings.GLOBAL_WITH_MODIFIED_FLAG, Boolean.TRUE );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue