HHH-8174 - Envers support for @NotFound
This commit is contained in:
parent
b4ab20a97b
commit
f2d435ddc1
|
@ -380,8 +380,12 @@
|
||||||
<para>
|
<para>
|
||||||
If you want to audit a relation, where the target entity is not audited (that is the case for example with
|
If you want to audit a relation, where the target entity is not audited (that is the case for example with
|
||||||
dictionary-like entities, which don't change and don't have to be audited), just annotate it with
|
dictionary-like entities, which don't change and don't have to be audited), just annotate it with
|
||||||
<literal>@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)</literal>. Then, when reading historic
|
<literal>@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)</literal>. Then, while reading historic
|
||||||
versions of your entity, the relation will always point to the "current" related entity.
|
versions of your entity, the relation will always point to the "current" related entity. By default Envers
|
||||||
|
throws <classname>javax.persistence.EntityNotFoundException</classname> when "current" entity does not
|
||||||
|
exist in the database. Apply <literal>@NotFound(action = NotFoundAction.IGNORE)</literal> annotation
|
||||||
|
to silence the exception and assign null value instead. Hereby solution causes implicit eager loading
|
||||||
|
of to-one relations.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -77,10 +77,8 @@ public final class ToOneRelationMetadataGenerator {
|
||||||
|
|
||||||
// Storing information about this relation
|
// Storing information about this relation
|
||||||
mainGenerator.getEntitiesConfigurations().get( entityName ).addToOneRelation(
|
mainGenerator.getEntitiesConfigurations().get( entityName ).addToOneRelation(
|
||||||
propertyAuditingData.getName(),
|
propertyAuditingData.getName(), referencedEntityName, relMapper,
|
||||||
referencedEntityName,
|
insertable, MappingTools.ignoreNotFound( value )
|
||||||
relMapper,
|
|
||||||
insertable
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the property isn't insertable, checking if this is not a "fake" bidirectional many-to-one relationship,
|
// If the property isn't insertable, checking if this is not a "fake" bidirectional many-to-one relationship,
|
||||||
|
@ -154,10 +152,8 @@ public final class ToOneRelationMetadataGenerator {
|
||||||
|
|
||||||
// Storing information about this relation
|
// Storing information about this relation
|
||||||
mainGenerator.getEntitiesConfigurations().get( entityName ).addToOneNotOwningRelation(
|
mainGenerator.getEntitiesConfigurations().get( entityName ).addToOneNotOwningRelation(
|
||||||
propertyAuditingData.getName(),
|
propertyAuditingData.getName(), owningReferencePropertyName, referencedEntityName,
|
||||||
owningReferencePropertyName,
|
ownedIdMapper, MappingTools.ignoreNotFound( value )
|
||||||
referencedEntityName,
|
|
||||||
ownedIdMapper
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Adding mapper for the id
|
// Adding mapper for the id
|
||||||
|
@ -191,10 +187,8 @@ public final class ToOneRelationMetadataGenerator {
|
||||||
|
|
||||||
// Storing information about this relation
|
// Storing information about this relation
|
||||||
mainGenerator.getEntitiesConfigurations().get( entityName ).addToOneRelation(
|
mainGenerator.getEntitiesConfigurations().get( entityName ).addToOneRelation(
|
||||||
propertyAuditingData.getName(),
|
propertyAuditingData.getName(), referencedEntityName, relMapper, insertable,
|
||||||
referencedEntityName,
|
MappingTools.ignoreNotFound( value )
|
||||||
relMapper,
|
|
||||||
insertable
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Adding mapper for the id
|
// Adding mapper for the id
|
||||||
|
|
|
@ -46,9 +46,8 @@ public class EntityConfiguration {
|
||||||
private Map<String, RelationDescription> relations;
|
private Map<String, RelationDescription> relations;
|
||||||
private String parentEntityName;
|
private String parentEntityName;
|
||||||
|
|
||||||
public EntityConfiguration(
|
public EntityConfiguration(String versionsEntityName, String entityClassName, IdMappingData idMappingData,
|
||||||
String versionsEntityName, String entityClassName, IdMappingData idMappingData,
|
ExtendedPropertyMapper propertyMapper, String parentEntityName) {
|
||||||
ExtendedPropertyMapper propertyMapper, String parentEntityName) {
|
|
||||||
this.versionsEntityName = versionsEntityName;
|
this.versionsEntityName = versionsEntityName;
|
||||||
this.entityClassName = entityClassName;
|
this.entityClassName = entityClassName;
|
||||||
this.idMappingData = idMappingData;
|
this.idMappingData = idMappingData;
|
||||||
|
@ -58,60 +57,36 @@ public class EntityConfiguration {
|
||||||
this.relations = new HashMap<String, RelationDescription>();
|
this.relations = new HashMap<String, RelationDescription>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToOneRelation(String fromPropertyName, String toEntityName, IdMapper idMapper, boolean insertable) {
|
public void addToOneRelation(String fromPropertyName, String toEntityName, IdMapper idMapper, boolean insertable,
|
||||||
|
boolean ignoreNotFound) {
|
||||||
relations.put(
|
relations.put(
|
||||||
fromPropertyName,
|
fromPropertyName,
|
||||||
new RelationDescription(
|
RelationDescription.toOne(
|
||||||
fromPropertyName,
|
fromPropertyName, RelationType.TO_ONE, toEntityName, null, idMapper, null,
|
||||||
RelationType.TO_ONE,
|
null, insertable, ignoreNotFound
|
||||||
toEntityName,
|
|
||||||
null,
|
|
||||||
idMapper,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
insertable
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToOneNotOwningRelation(
|
public void addToOneNotOwningRelation(String fromPropertyName, String mappedByPropertyName,
|
||||||
String fromPropertyName,
|
String toEntityName, IdMapper idMapper, boolean ignoreNotFound) {
|
||||||
String mappedByPropertyName,
|
|
||||||
String toEntityName,
|
|
||||||
IdMapper idMapper) {
|
|
||||||
relations.put(
|
relations.put(
|
||||||
fromPropertyName,
|
fromPropertyName,
|
||||||
new RelationDescription(
|
RelationDescription.toOne(
|
||||||
fromPropertyName,
|
fromPropertyName, RelationType.TO_ONE_NOT_OWNING, toEntityName, mappedByPropertyName,
|
||||||
RelationType.TO_ONE_NOT_OWNING,
|
idMapper, null, null, true, ignoreNotFound
|
||||||
toEntityName,
|
|
||||||
mappedByPropertyName,
|
|
||||||
idMapper,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToManyNotOwningRelation(
|
public void addToManyNotOwningRelation(String fromPropertyName, String mappedByPropertyName, String toEntityName,
|
||||||
String fromPropertyName,
|
IdMapper idMapper, PropertyMapper fakeBidirectionalRelationMapper,
|
||||||
String mappedByPropertyName,
|
PropertyMapper fakeBidirectionalRelationIndexMapper) {
|
||||||
String toEntityName,
|
|
||||||
IdMapper idMapper,
|
|
||||||
PropertyMapper fakeBidirectionalRelationMapper,
|
|
||||||
PropertyMapper fakeBidirectionalRelationIndexMapper) {
|
|
||||||
relations.put(
|
relations.put(
|
||||||
fromPropertyName,
|
fromPropertyName,
|
||||||
new RelationDescription(
|
RelationDescription.toMany(
|
||||||
fromPropertyName,
|
fromPropertyName, RelationType.TO_MANY_NOT_OWNING, toEntityName, mappedByPropertyName,
|
||||||
RelationType.TO_MANY_NOT_OWNING,
|
idMapper, fakeBidirectionalRelationMapper, fakeBidirectionalRelationIndexMapper, true
|
||||||
toEntityName,
|
|
||||||
mappedByPropertyName,
|
|
||||||
idMapper,
|
|
||||||
fakeBidirectionalRelationMapper,
|
|
||||||
fakeBidirectionalRelationIndexMapper,
|
|
||||||
true
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -119,34 +94,18 @@ public class EntityConfiguration {
|
||||||
public void addToManyMiddleRelation(String fromPropertyName, String toEntityName) {
|
public void addToManyMiddleRelation(String fromPropertyName, String toEntityName) {
|
||||||
relations.put(
|
relations.put(
|
||||||
fromPropertyName,
|
fromPropertyName,
|
||||||
new RelationDescription(
|
RelationDescription.toMany(
|
||||||
fromPropertyName,
|
fromPropertyName, RelationType.TO_MANY_MIDDLE, toEntityName, null, null, null, null, true
|
||||||
RelationType.TO_MANY_MIDDLE,
|
|
||||||
toEntityName,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToManyMiddleNotOwningRelation(
|
public void addToManyMiddleNotOwningRelation(String fromPropertyName, String mappedByPropertyName, String toEntityName) {
|
||||||
String fromPropertyName,
|
|
||||||
String mappedByPropertyName,
|
|
||||||
String toEntityName) {
|
|
||||||
relations.put(
|
relations.put(
|
||||||
fromPropertyName,
|
fromPropertyName,
|
||||||
new RelationDescription(
|
RelationDescription.toMany(
|
||||||
fromPropertyName,
|
fromPropertyName, RelationType.TO_MANY_MIDDLE_NOT_OWNING, toEntityName, mappedByPropertyName,
|
||||||
RelationType.TO_MANY_MIDDLE_NOT_OWNING,
|
null, null, null, true
|
||||||
toEntityName,
|
|
||||||
mappedByPropertyName,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
true
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -175,6 +134,13 @@ public class EntityConfiguration {
|
||||||
return parentEntityName;
|
return parentEntityName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the className for the configured entity
|
||||||
|
*/
|
||||||
|
public String getEntityClassName() {
|
||||||
|
return entityClassName;
|
||||||
|
}
|
||||||
|
|
||||||
// For use by EntitiesConfigurations
|
// For use by EntitiesConfigurations
|
||||||
|
|
||||||
String getVersionsEntityName() {
|
String getVersionsEntityName() {
|
||||||
|
@ -184,11 +150,4 @@ public class EntityConfiguration {
|
||||||
Iterable<RelationDescription> getRelationsIterator() {
|
Iterable<RelationDescription> getRelationsIterator() {
|
||||||
return relations.values();
|
return relations.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the className for the configured entity
|
|
||||||
*/
|
|
||||||
public String getEntityClassName() {
|
|
||||||
return entityClassName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,21 +34,44 @@ public class RelationDescription {
|
||||||
private final RelationType relationType;
|
private final RelationType relationType;
|
||||||
private final String toEntityName;
|
private final String toEntityName;
|
||||||
private final String mappedByPropertyName;
|
private final String mappedByPropertyName;
|
||||||
|
private final boolean ignoreNotFound;
|
||||||
private final IdMapper idMapper;
|
private final IdMapper idMapper;
|
||||||
private final PropertyMapper fakeBidirectionalRelationMapper;
|
private final PropertyMapper fakeBidirectionalRelationMapper;
|
||||||
private final PropertyMapper fakeBidirectionalRelationIndexMapper;
|
private final PropertyMapper fakeBidirectionalRelationIndexMapper;
|
||||||
private final boolean insertable;
|
private final boolean insertable;
|
||||||
private boolean bidirectional;
|
private boolean bidirectional;
|
||||||
|
|
||||||
public RelationDescription(
|
public static RelationDescription toOne(String fromPropertyName, RelationType relationType, String toEntityName,
|
||||||
String fromPropertyName, RelationType relationType, String toEntityName,
|
String mappedByPropertyName, IdMapper idMapper, PropertyMapper fakeBidirectionalRelationMapper,
|
||||||
String mappedByPropertyName, IdMapper idMapper,
|
PropertyMapper fakeBidirectionalRelationIndexMapper, boolean insertable,
|
||||||
PropertyMapper fakeBidirectionalRelationMapper,
|
boolean ignoreNotFound) {
|
||||||
PropertyMapper fakeBidirectionalRelationIndexMapper, boolean insertable) {
|
return new RelationDescription(
|
||||||
|
fromPropertyName, relationType, toEntityName, mappedByPropertyName, idMapper, fakeBidirectionalRelationMapper,
|
||||||
|
fakeBidirectionalRelationIndexMapper, insertable, ignoreNotFound
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RelationDescription toMany(String fromPropertyName, RelationType relationType, String toEntityName,
|
||||||
|
String mappedByPropertyName, IdMapper idMapper, PropertyMapper fakeBidirectionalRelationMapper,
|
||||||
|
PropertyMapper fakeBidirectionalRelationIndexMapper, boolean insertable) {
|
||||||
|
// Envers populates collections by executing dedicated queries. Special handling of
|
||||||
|
// @NotFound(action = NotFoundAction.IGNORE) can be omitted in such case as exceptions
|
||||||
|
// (e.g. EntityNotFoundException, ObjectNotFoundException) are never thrown.
|
||||||
|
// Therefore assigning false to ignoreNotFound.
|
||||||
|
return new RelationDescription(
|
||||||
|
fromPropertyName, relationType, toEntityName, mappedByPropertyName, idMapper, fakeBidirectionalRelationMapper,
|
||||||
|
fakeBidirectionalRelationIndexMapper, insertable, false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RelationDescription(String fromPropertyName, RelationType relationType, String toEntityName,
|
||||||
|
String mappedByPropertyName, IdMapper idMapper, PropertyMapper fakeBidirectionalRelationMapper,
|
||||||
|
PropertyMapper fakeBidirectionalRelationIndexMapper, boolean insertable, boolean ignoreNotFound) {
|
||||||
this.fromPropertyName = fromPropertyName;
|
this.fromPropertyName = fromPropertyName;
|
||||||
this.relationType = relationType;
|
this.relationType = relationType;
|
||||||
this.toEntityName = toEntityName;
|
this.toEntityName = toEntityName;
|
||||||
this.mappedByPropertyName = mappedByPropertyName;
|
this.mappedByPropertyName = mappedByPropertyName;
|
||||||
|
this.ignoreNotFound = ignoreNotFound;
|
||||||
this.idMapper = idMapper;
|
this.idMapper = idMapper;
|
||||||
this.fakeBidirectionalRelationMapper = fakeBidirectionalRelationMapper;
|
this.fakeBidirectionalRelationMapper = fakeBidirectionalRelationMapper;
|
||||||
this.fakeBidirectionalRelationIndexMapper = fakeBidirectionalRelationIndexMapper;
|
this.fakeBidirectionalRelationIndexMapper = fakeBidirectionalRelationIndexMapper;
|
||||||
|
@ -73,6 +96,10 @@ public class RelationDescription {
|
||||||
return mappedByPropertyName;
|
return mappedByPropertyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isIgnoreNotFound() {
|
||||||
|
return ignoreNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
public IdMapper getIdMapper() {
|
public IdMapper getIdMapper() {
|
||||||
return idMapper;
|
return idMapper;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@ import org.hibernate.persister.entity.EntityPersister;
|
||||||
*/
|
*/
|
||||||
public class ToOneEntityLoader {
|
public class ToOneEntityLoader {
|
||||||
/**
|
/**
|
||||||
* Immediately loads historical entity or its current state when excluded from audit process.
|
* Immediately loads historical entity or its current state when excluded from audit process. Returns {@code null}
|
||||||
|
* reference if entity has not been found in the database.
|
||||||
*/
|
*/
|
||||||
public static Object loadImmediate(
|
public static Object loadImmediate(
|
||||||
AuditReaderImplementor versionsReader,
|
AuditReaderImplementor versionsReader,
|
||||||
|
|
|
@ -45,11 +45,8 @@ public class ToOneIdMapper extends AbstractToOneMapper {
|
||||||
private final String referencedEntityName;
|
private final String referencedEntityName;
|
||||||
private final boolean nonInsertableFake;
|
private final boolean nonInsertableFake;
|
||||||
|
|
||||||
public ToOneIdMapper(
|
public ToOneIdMapper(IdMapper delegate, PropertyData propertyData, String referencedEntityName,
|
||||||
IdMapper delegate,
|
boolean nonInsertableFake) {
|
||||||
PropertyData propertyData,
|
|
||||||
String referencedEntityName,
|
|
||||||
boolean nonInsertableFake) {
|
|
||||||
super( propertyData );
|
super( propertyData );
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
this.referencedEntityName = referencedEntityName;
|
this.referencedEntityName = referencedEntityName;
|
||||||
|
@ -57,11 +54,8 @@ public class ToOneIdMapper extends AbstractToOneMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mapToMapFromEntity(
|
public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj,
|
||||||
SessionImplementor session,
|
Object oldObj) {
|
||||||
Map<String, Object> data,
|
|
||||||
Object newObj,
|
|
||||||
Object oldObj) {
|
|
||||||
final HashMap<String, Object> newData = new HashMap<String, Object>();
|
final HashMap<String, Object> newData = new HashMap<String, Object>();
|
||||||
|
|
||||||
// If this property is originally non-insertable, but made insertable because it is in a many-to-one "fake"
|
// If this property is originally non-insertable, but made insertable because it is in a many-to-one "fake"
|
||||||
|
@ -77,11 +71,8 @@ public class ToOneIdMapper extends AbstractToOneMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mapModifiedFlagsToMapFromEntity(
|
public void mapModifiedFlagsToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj,
|
||||||
SessionImplementor session,
|
Object oldObj) {
|
||||||
Map<String, Object> data,
|
|
||||||
Object newObj,
|
|
||||||
Object oldObj) {
|
|
||||||
if ( getPropertyData().isUsingModifiedFlag() ) {
|
if ( getPropertyData().isUsingModifiedFlag() ) {
|
||||||
data.put( getPropertyData().getModifiedFlagPropertyName(), checkModified( session, newObj, oldObj ) );
|
data.put( getPropertyData().getModifiedFlagPropertyName(), checkModified( session, newObj, oldObj ) );
|
||||||
}
|
}
|
||||||
|
@ -103,9 +94,8 @@ public class ToOneIdMapper extends AbstractToOneMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nullSafeMapToEntityFromMap(
|
public void nullSafeMapToEntityFromMap(AuditConfiguration verCfg, Object obj, Map data, Object primaryKey,
|
||||||
AuditConfiguration verCfg, Object obj, Map data, Object primaryKey,
|
AuditReaderImplementor versionsReader, Number revision) {
|
||||||
AuditReaderImplementor versionsReader, Number revision) {
|
|
||||||
final Object entityId = delegate.mapToIdFromMap( data );
|
final Object entityId = delegate.mapToIdFromMap( data );
|
||||||
Object value = null;
|
Object value = null;
|
||||||
if ( entityId != null ) {
|
if ( entityId != null ) {
|
||||||
|
@ -114,27 +104,35 @@ public class ToOneIdMapper extends AbstractToOneMapper {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final EntityInfo referencedEntity = getEntityInfo( verCfg, referencedEntityName );
|
final EntityInfo referencedEntity = getEntityInfo( verCfg, referencedEntityName );
|
||||||
value = ToOneEntityLoader.createProxyOrLoadImmediate(
|
boolean ignoreNotFound = false;
|
||||||
versionsReader, referencedEntity.getEntityClass(), referencedEntityName,
|
if ( !referencedEntity.isAudited() ) {
|
||||||
entityId, revision, RevisionType.DEL.equals(
|
final String referencingEntityName = verCfg.getEntCfg().getEntityNameForVersionsEntityName( (String) data.get( "$type$" ) );
|
||||||
data.get(
|
ignoreNotFound = verCfg.getEntCfg().get( referencingEntityName ).getRelationDescription( getPropertyData().getName() ).isIgnoreNotFound();
|
||||||
verCfg.getAuditEntCfg()
|
}
|
||||||
.getRevisionTypePropName()
|
if ( ignoreNotFound ) {
|
||||||
)
|
// Eagerly loading referenced entity to silence potential (in case of proxy)
|
||||||
), verCfg
|
// EntityNotFoundException or ObjectNotFoundException. Assigning null reference.
|
||||||
);
|
value = ToOneEntityLoader.loadImmediate(
|
||||||
|
versionsReader, referencedEntity.getEntityClass(), referencedEntityName,
|
||||||
|
entityId, revision, RevisionType.DEL.equals( data.get( verCfg.getAuditEntCfg().getRevisionTypePropName() ) ),
|
||||||
|
verCfg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value = ToOneEntityLoader.createProxyOrLoadImmediate(
|
||||||
|
versionsReader, referencedEntity.getEntityClass(), referencedEntityName,
|
||||||
|
entityId, revision, RevisionType.DEL.equals( data.get( verCfg.getAuditEntCfg().getRevisionTypePropName() ) ),
|
||||||
|
verCfg
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setPropertyValue( obj, value );
|
setPropertyValue( obj, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMiddleEqualToQuery(
|
public void addMiddleEqualToQuery(Parameters parameters, String idPrefix1, String prefix1,
|
||||||
Parameters parameters,
|
String idPrefix2, String prefix2) {
|
||||||
String idPrefix1,
|
|
||||||
String prefix1,
|
|
||||||
String idPrefix2,
|
|
||||||
String prefix2) {
|
|
||||||
delegate.addIdsEqualToQuery( parameters, prefix1, delegate, prefix2 );
|
delegate.addIdsEqualToQuery( parameters, prefix1, delegate, prefix2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
package org.hibernate.envers.internal.tools;
|
package org.hibernate.envers.internal.tools;
|
||||||
|
|
||||||
import org.hibernate.mapping.Collection;
|
import org.hibernate.mapping.Collection;
|
||||||
|
import org.hibernate.mapping.ManyToOne;
|
||||||
import org.hibernate.mapping.OneToMany;
|
import org.hibernate.mapping.OneToMany;
|
||||||
import org.hibernate.mapping.ToOne;
|
import org.hibernate.mapping.ToOne;
|
||||||
import org.hibernate.mapping.Value;
|
import org.hibernate.mapping.Value;
|
||||||
|
@ -63,4 +64,18 @@ public abstract class MappingTools {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param value Persistent property.
|
||||||
|
* @return {@code false} if lack of associated entity shall raise an exception, {@code true} otherwise.
|
||||||
|
*/
|
||||||
|
public static boolean ignoreNotFound(Value value) {
|
||||||
|
if ( value instanceof ManyToOne ) {
|
||||||
|
return ( (ManyToOne) value ).isIgnoreNotFound();
|
||||||
|
}
|
||||||
|
else if ( value instanceof OneToMany ) {
|
||||||
|
return ( (OneToMany) value ).isIgnoreNotFound();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.envers.test.entities.manytomany.unidirectional;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.NotFound;
|
||||||
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.RelationTargetAuditMode;
|
||||||
|
import org.hibernate.envers.test.entities.UnversionedStrTestEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
@Audited
|
||||||
|
@Entity
|
||||||
|
@Table(name = "M2M_N_AUD_NULL")
|
||||||
|
public class ManyToManyNotAuditedNullEntity implements Serializable {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY)
|
||||||
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
|
private List<UnversionedStrTestEntity> references = new ArrayList<UnversionedStrTestEntity>();
|
||||||
|
|
||||||
|
protected ManyToManyNotAuditedNullEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToManyNotAuditedNullEntity(Integer id, String data) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) return true;
|
||||||
|
if ( !( o instanceof ManyToManyNotAuditedNullEntity ) ) return false;
|
||||||
|
|
||||||
|
ManyToManyNotAuditedNullEntity that = (ManyToManyNotAuditedNullEntity) o;
|
||||||
|
|
||||||
|
if ( data != null ? !data.equals( that.getData() ) : that.getData() != null ) return false;
|
||||||
|
if ( id != null ? !id.equals( that.getId() ) : that.getId() != null ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
int result = ( id != null ? id.hashCode() : 0 );
|
||||||
|
result = 31 * result + ( data != null ? data.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "ManyToManyNotAuditedNullEntity(id = " + id + ", data = " + data + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UnversionedStrTestEntity> getReferences() {
|
||||||
|
return references;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReferences(List<UnversionedStrTestEntity> references) {
|
||||||
|
this.references = references;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.envers.test.entities.manytoone.unidirectional;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.NotFound;
|
||||||
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.RelationTargetAuditMode;
|
||||||
|
import org.hibernate.envers.test.entities.UnversionedStrTestEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
@Audited
|
||||||
|
@Entity
|
||||||
|
@Table(name = "M2O_N_AUD_NULL")
|
||||||
|
public class ManyToOneNotAuditedNullEntity implements Serializable {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY, optional = true)
|
||||||
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
|
private UnversionedStrTestEntity reference;
|
||||||
|
|
||||||
|
protected ManyToOneNotAuditedNullEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToOneNotAuditedNullEntity(Integer id, String data, UnversionedStrTestEntity reference) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
this.reference = reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) return true;
|
||||||
|
if ( !( o instanceof ManyToOneNotAuditedNullEntity ) ) return false;
|
||||||
|
|
||||||
|
ManyToOneNotAuditedNullEntity that = (ManyToOneNotAuditedNullEntity) o;
|
||||||
|
|
||||||
|
if ( data != null ? !data.equals( that.getData() ) : that.getData() != null ) return false;
|
||||||
|
if ( id != null ? !id.equals( that.getId() ) : that.getId() != null ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
int result = ( id != null ? id.hashCode() : 0 );
|
||||||
|
result = 31 * result + ( data != null ? data.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "ManyToOneNotAuditedNullEntity(id = " + id + ", data = " + data + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnversionedStrTestEntity getReference() {
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReference(UnversionedStrTestEntity reference) {
|
||||||
|
this.reference = reference;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, 2013, Red Hat Inc. or third-party contributors as
|
||||||
|
* indicated by the @author tags or express copyright attribution
|
||||||
|
* statements applied by the authors. All third-party contributions are
|
||||||
|
* distributed under license by Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||||
|
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||||
|
* Lesser General Public License, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this distribution; if not, write to:
|
||||||
|
* Free Software Foundation, Inc.
|
||||||
|
* 51 Franklin Street, Fifth Floor
|
||||||
|
* Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
package org.hibernate.envers.test.entities.onetomany;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.NotFound;
|
||||||
|
import org.hibernate.annotations.NotFoundAction;
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.RelationTargetAuditMode;
|
||||||
|
import org.hibernate.envers.test.entities.UnversionedStrTestEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com)
|
||||||
|
*/
|
||||||
|
@Audited
|
||||||
|
@Entity
|
||||||
|
@Table(name = "O2M_N_AUD_NULL")
|
||||||
|
public class OneToManyNotAuditedNullEntity implements Serializable {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
|
||||||
|
@OneToMany(fetch = FetchType.LAZY)
|
||||||
|
@NotFound(action = NotFoundAction.IGNORE)
|
||||||
|
private List<UnversionedStrTestEntity> references = new ArrayList<UnversionedStrTestEntity>();
|
||||||
|
|
||||||
|
protected OneToManyNotAuditedNullEntity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public OneToManyNotAuditedNullEntity(Integer id, String data) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) return true;
|
||||||
|
if ( !( o instanceof OneToManyNotAuditedNullEntity ) ) return false;
|
||||||
|
|
||||||
|
OneToManyNotAuditedNullEntity that = (OneToManyNotAuditedNullEntity) o;
|
||||||
|
|
||||||
|
if ( data != null ? !data.equals( that.getData() ) : that.getData() != null ) return false;
|
||||||
|
if ( id != null ? !id.equals( that.getId() ) : that.getId() != null ) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
int result = ( id != null ? id.hashCode() : 0 );
|
||||||
|
result = 31 * result + ( data != null ? data.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "OneToManyNotAuditedNullEntity(id = " + id + ", data = " + data + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UnversionedStrTestEntity> getReferences() {
|
||||||
|
return references;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReferences(List<UnversionedStrTestEntity> references) {
|
||||||
|
this.references = references;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,26 +25,37 @@ package org.hibernate.envers.test.integration.proxy;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
import org.hibernate.envers.test.Priority;
|
import org.hibernate.envers.test.Priority;
|
||||||
import org.hibernate.envers.test.entities.UnversionedStrTestEntity;
|
import org.hibernate.envers.test.entities.UnversionedStrTestEntity;
|
||||||
|
import org.hibernate.envers.test.entities.manytomany.unidirectional.ManyToManyNotAuditedNullEntity;
|
||||||
|
import org.hibernate.envers.test.entities.manytoone.unidirectional.ManyToOneNotAuditedNullEntity;
|
||||||
import org.hibernate.envers.test.entities.manytoone.unidirectional.TargetNotAuditedEntity;
|
import org.hibernate.envers.test.entities.manytoone.unidirectional.TargetNotAuditedEntity;
|
||||||
|
import org.hibernate.envers.test.entities.onetomany.OneToManyNotAuditedNullEntity;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.proxy.LazyInitializer;
|
import org.hibernate.proxy.LazyInitializer;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Eugene Goroschenya
|
* @author Eugene Goroschenya
|
||||||
*/
|
*/
|
||||||
public class ProxyIdentifier extends BaseEnversJPAFunctionalTestCase {
|
public class ProxyIdentifier extends BaseEnversJPAFunctionalTestCase {
|
||||||
private TargetNotAuditedEntity tnae1;
|
private TargetNotAuditedEntity tnae1 = null;
|
||||||
private UnversionedStrTestEntity uste1;
|
private ManyToOneNotAuditedNullEntity mtonane1 = null;
|
||||||
|
private ManyToManyNotAuditedNullEntity mtmnane1 = null;
|
||||||
|
private OneToManyNotAuditedNullEntity otmnane1 = null;
|
||||||
|
private UnversionedStrTestEntity uste1 = null;
|
||||||
|
private UnversionedStrTestEntity uste2 = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
return new Class[] {TargetNotAuditedEntity.class, UnversionedStrTestEntity.class};
|
return new Class[] {
|
||||||
|
TargetNotAuditedEntity.class, ManyToOneNotAuditedNullEntity.class, UnversionedStrTestEntity.class,
|
||||||
|
ManyToManyNotAuditedNullEntity.class, OneToManyNotAuditedNullEntity.class
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -53,10 +64,12 @@ public class ProxyIdentifier extends BaseEnversJPAFunctionalTestCase {
|
||||||
EntityManager em = getEntityManager();
|
EntityManager em = getEntityManager();
|
||||||
|
|
||||||
uste1 = new UnversionedStrTestEntity( "str1" );
|
uste1 = new UnversionedStrTestEntity( "str1" );
|
||||||
|
uste2 = new UnversionedStrTestEntity( "str2" );
|
||||||
|
|
||||||
// No revision
|
// No revision
|
||||||
em.getTransaction().begin();
|
em.getTransaction().begin();
|
||||||
em.persist( uste1 );
|
em.persist( uste1 );
|
||||||
|
em.persist( uste2 );
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
|
|
||||||
// Revision 1
|
// Revision 1
|
||||||
|
@ -65,24 +78,73 @@ public class ProxyIdentifier extends BaseEnversJPAFunctionalTestCase {
|
||||||
tnae1 = new TargetNotAuditedEntity( 1, "tnae1", uste1 );
|
tnae1 = new TargetNotAuditedEntity( 1, "tnae1", uste1 );
|
||||||
em.persist( tnae1 );
|
em.persist( tnae1 );
|
||||||
em.getTransaction().commit();
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
// Revision 2
|
||||||
|
em.getTransaction().begin();
|
||||||
|
uste2 = em.find( UnversionedStrTestEntity.class, uste2.getId() );
|
||||||
|
mtonane1 = new ManyToOneNotAuditedNullEntity( 2, "mtonane1", uste2 );
|
||||||
|
mtmnane1 = new ManyToManyNotAuditedNullEntity( 3, "mtmnane1" );
|
||||||
|
mtmnane1.getReferences().add( uste2 );
|
||||||
|
otmnane1 = new OneToManyNotAuditedNullEntity( 4, "otmnane1" );
|
||||||
|
otmnane1.getReferences().add( uste2 );
|
||||||
|
em.persist( mtonane1 );
|
||||||
|
em.persist( mtmnane1 );
|
||||||
|
em.persist( otmnane1 );
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
em.clear();
|
||||||
|
|
||||||
|
// Revision 3
|
||||||
|
// Remove not audited target entity, so we can verify null reference
|
||||||
|
// when @NotFound(action = NotFoundAction.IGNORE) applied.
|
||||||
|
em.getTransaction().begin();
|
||||||
|
ManyToOneNotAuditedNullEntity tmp1 = em.find( ManyToOneNotAuditedNullEntity.class, mtonane1.getId() );
|
||||||
|
tmp1.setReference( null );
|
||||||
|
tmp1 = em.merge( tmp1 );
|
||||||
|
ManyToManyNotAuditedNullEntity tmp2 = em.find( ManyToManyNotAuditedNullEntity.class, mtmnane1.getId() );
|
||||||
|
tmp2.setReferences( null );
|
||||||
|
tmp2 = em.merge( tmp2 );
|
||||||
|
OneToManyNotAuditedNullEntity tmp3 = em.find( OneToManyNotAuditedNullEntity.class, otmnane1.getId() );
|
||||||
|
tmp3.setReferences( null );
|
||||||
|
tmp3 = em.merge( tmp3 );
|
||||||
|
em.remove( em.getReference( UnversionedStrTestEntity.class, uste2.getId() ) );
|
||||||
|
em.getTransaction().commit();
|
||||||
|
|
||||||
|
em.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testProxyIdentifier() {
|
public void testProxyIdentifier() {
|
||||||
TargetNotAuditedEntity rev1 = getAuditReader().find( TargetNotAuditedEntity.class, tnae1.getId(), 1 );
|
TargetNotAuditedEntity rev1 = getAuditReader().find( TargetNotAuditedEntity.class, tnae1.getId(), 1 );
|
||||||
|
|
||||||
assert rev1.getReference() instanceof HibernateProxy;
|
Assert.assertTrue( rev1.getReference() instanceof HibernateProxy );
|
||||||
|
|
||||||
HibernateProxy proxyCreateByEnvers = (HibernateProxy) rev1.getReference();
|
HibernateProxy proxyCreateByEnvers = (HibernateProxy) rev1.getReference();
|
||||||
LazyInitializer lazyInitializer = proxyCreateByEnvers.getHibernateLazyInitializer();
|
LazyInitializer lazyInitializer = proxyCreateByEnvers.getHibernateLazyInitializer();
|
||||||
|
|
||||||
assert lazyInitializer.isUninitialized();
|
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
||||||
assert lazyInitializer.getIdentifier() != null;
|
Assert.assertNotNull( lazyInitializer.getIdentifier() );
|
||||||
assert lazyInitializer.getIdentifier().equals( tnae1.getId() );
|
Assert.assertEquals( tnae1.getId(), lazyInitializer.getIdentifier() );
|
||||||
assert lazyInitializer.isUninitialized();
|
Assert.assertTrue( lazyInitializer.isUninitialized() );
|
||||||
|
|
||||||
assert rev1.getReference().getId().equals( uste1.getId() );
|
Assert.assertEquals( uste1.getId(), rev1.getReference().getId() );
|
||||||
assert rev1.getReference().getStr().equals( uste1.getStr() );
|
Assert.assertEquals( uste1.getStr(), rev1.getReference().getStr() );
|
||||||
assert !lazyInitializer.isUninitialized();
|
Assert.assertFalse( lazyInitializer.isUninitialized() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue( jiraKey = "HHH-8174" )
|
||||||
|
public void testNullReferenceWithNotFoundActionIgnore() {
|
||||||
|
ManyToOneNotAuditedNullEntity mtoRev2 = getAuditReader().find( ManyToOneNotAuditedNullEntity.class, mtonane1.getId(), 2 );
|
||||||
|
Assert.assertEquals( mtonane1, mtoRev2 );
|
||||||
|
Assert.assertNull( mtoRev2.getReference() );
|
||||||
|
|
||||||
|
ManyToManyNotAuditedNullEntity mtmRev2 = getAuditReader().find( ManyToManyNotAuditedNullEntity.class, mtmnane1.getId(), 2 );
|
||||||
|
Assert.assertEquals( mtmnane1, mtmRev2 );
|
||||||
|
Assert.assertTrue( mtmRev2.getReferences().isEmpty() );
|
||||||
|
|
||||||
|
OneToManyNotAuditedNullEntity otmRev2 = getAuditReader().find( OneToManyNotAuditedNullEntity.class, otmnane1.getId(), 2 );
|
||||||
|
Assert.assertEquals( otmnane1, otmRev2 );
|
||||||
|
Assert.assertTrue( otmRev2.getReferences().isEmpty() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue