HHH-7138 - Hibernate implements JPA @OneToMany collection versioning incorrectly
This commit is contained in:
parent
94e79944b8
commit
05c3679373
|
@ -436,8 +436,15 @@ public abstract class CollectionBinder {
|
|||
}
|
||||
|
||||
collection.setMutable( !property.isAnnotationPresent( Immutable.class ) );
|
||||
OptimisticLock lockAnn = property.getAnnotation( OptimisticLock.class );
|
||||
if ( lockAnn != null ) collection.setOptimisticLocked( !lockAnn.excluded() );
|
||||
|
||||
//work on association
|
||||
boolean isMappedBy = !BinderHelper.isEmptyAnnotationValue( mappedBy );
|
||||
|
||||
final OptimisticLock lockAnn = property.getAnnotation( OptimisticLock.class );
|
||||
final boolean includeInOptimisticLockChecks = ( lockAnn != null )
|
||||
? ! lockAnn.excluded()
|
||||
: ! isMappedBy;
|
||||
collection.setOptimisticLocked( includeInOptimisticLockChecks );
|
||||
|
||||
Persister persisterAnn = property.getAnnotation( Persister.class );
|
||||
if ( persisterAnn != null ) {
|
||||
|
@ -512,9 +519,6 @@ public abstract class CollectionBinder {
|
|||
collection.setLoaderName( loader.namedQuery() );
|
||||
}
|
||||
|
||||
//work on association
|
||||
boolean isMappedBy = !BinderHelper.isEmptyAnnotationValue( mappedBy );
|
||||
|
||||
if (isMappedBy
|
||||
&& (property.isAnnotationPresent( JoinColumn.class )
|
||||
|| property.isAnnotationPresent( JoinColumns.class )
|
||||
|
|
|
@ -48,12 +48,14 @@ import org.hibernate.cfg.PropertyHolder;
|
|||
import org.hibernate.cfg.PropertyPreloadedData;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.mapping.Collection;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.mapping.KeyValue;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.mapping.RootClass;
|
||||
import org.hibernate.mapping.SimpleValue;
|
||||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.mapping.Value;
|
||||
|
||||
/**
|
||||
|
@ -296,27 +298,46 @@ public class PropertyBinder {
|
|||
prop.setInsertable( insertable );
|
||||
prop.setUpdateable( updatable );
|
||||
|
||||
OptimisticLock lockAnn = property != null ?
|
||||
property.getAnnotation( OptimisticLock.class ) :
|
||||
null;
|
||||
if ( lockAnn != null ) {
|
||||
prop.setOptimisticLocked( !lockAnn.excluded() );
|
||||
//TODO this should go to the core as a mapping validation checking
|
||||
if ( lockAnn.excluded() && (
|
||||
property.isAnnotationPresent( javax.persistence.Version.class )
|
||||
|| property.isAnnotationPresent( Id.class )
|
||||
|| property.isAnnotationPresent( EmbeddedId.class ) ) ) {
|
||||
throw new AnnotationException(
|
||||
"@OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version: "
|
||||
+ StringHelper.qualify( holder.getPath(), name )
|
||||
);
|
||||
}
|
||||
// this is already handled for collections in CollectionBinder...
|
||||
if ( Collection.class.isInstance( value ) ) {
|
||||
prop.setOptimisticLocked( ( (Collection) value ).isOptimisticLocked() );
|
||||
}
|
||||
else {
|
||||
final OptimisticLock lockAnn = property != null
|
||||
? property.getAnnotation( OptimisticLock.class )
|
||||
: null;
|
||||
if ( lockAnn != null ) {
|
||||
//TODO this should go to the core as a mapping validation checking
|
||||
if ( lockAnn.excluded() && (
|
||||
property.isAnnotationPresent( javax.persistence.Version.class )
|
||||
|| property.isAnnotationPresent( Id.class )
|
||||
|| property.isAnnotationPresent( EmbeddedId.class ) ) ) {
|
||||
throw new AnnotationException(
|
||||
"@OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version: "
|
||||
+ StringHelper.qualify( holder.getPath(), name )
|
||||
);
|
||||
}
|
||||
}
|
||||
final boolean isOwnedValue = !isToOneValue( value ) || insertable; // && updatable as well???
|
||||
final boolean includeInOptimisticLockChecks = ( lockAnn != null )
|
||||
? ! lockAnn.excluded()
|
||||
: isOwnedValue;
|
||||
prop.setOptimisticLocked( includeInOptimisticLockChecks );
|
||||
}
|
||||
|
||||
LOG.tracev( "Cascading {0} with {1}", name, cascade );
|
||||
this.mappingProperty = prop;
|
||||
return prop;
|
||||
}
|
||||
|
||||
private boolean isCollection(Value value) {
|
||||
return Collection.class.isInstance( value );
|
||||
}
|
||||
|
||||
private boolean isToOneValue(Value value) {
|
||||
return ToOne.class.isInstance( value );
|
||||
}
|
||||
|
||||
public void setProperty(XProperty property) {
|
||||
this.property = property;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ public class JpaSpecVersionValueUpdatingTest extends BaseCoreFunctionalTestCase
|
|||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected( jiraKey = "HHH-7138" )
|
||||
public void testVersionNotIncrementedOnModificationOfNonOwningCollectionNonCascaded() {
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
@ -98,12 +97,6 @@ public class JpaSpecVersionValueUpdatingTest extends BaseCoreFunctionalTestCase
|
|||
Customer customer = new Customer();
|
||||
customer.id = 1L;
|
||||
|
||||
Order order = new Order();
|
||||
order.id = 1L;
|
||||
|
||||
order.customer = customer;
|
||||
customer.orders.add( order );
|
||||
|
||||
Session session = openSession();
|
||||
session.beginTransaction();
|
||||
session.save( customer );
|
||||
|
@ -112,6 +105,19 @@ public class JpaSpecVersionValueUpdatingTest extends BaseCoreFunctionalTestCase
|
|||
|
||||
long initial = customer.version;
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
customer = (Customer) session.get( Customer.class, 1L );
|
||||
assertEquals( initial, customer.version );
|
||||
Order order = new Order();
|
||||
order.id = 1L;
|
||||
order.customer = customer;
|
||||
customer.orders.add( order );
|
||||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
assertEquals( initial, customer.version );
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
customer = (Customer) session.get( Customer.class, 1L );
|
||||
|
@ -122,6 +128,7 @@ public class JpaSpecVersionValueUpdatingTest extends BaseCoreFunctionalTestCase
|
|||
session.getTransaction().commit();
|
||||
session.close();
|
||||
|
||||
assertEquals( initial, customer.version );
|
||||
|
||||
session = openSession();
|
||||
session.beginTransaction();
|
||||
|
|
Loading…
Reference in New Issue