HHH-13466 : ClassCastException when changing a Collection association to a Set if @PreUpdate listener exists

(cherry picked from commit 7d54b59743)
This commit is contained in:
Gail Badner 2019-06-26 12:09:05 -07:00 committed by gbadner
parent 1d316e6452
commit f7498b2340
4 changed files with 41 additions and 4 deletions

View File

@ -36,6 +36,9 @@ public class PersistentBag extends AbstractPersistentCollection implements List
protected List bag;
// The Collection provided to a PersistentBag constructor,
private Collection providedCollection;
/**
* Constructs a PersistentBag. Needed for SOAP libraries, etc
*/
@ -72,6 +75,7 @@ public class PersistentBag extends AbstractPersistentCollection implements List
@SuppressWarnings("unchecked")
public PersistentBag(SharedSessionContractImplementor session, Collection coll) {
super( session );
providedCollection = coll;
if ( coll instanceof List ) {
bag = (List) coll;
}
@ -101,7 +105,12 @@ public class PersistentBag extends AbstractPersistentCollection implements List
@Override
public boolean isWrapper(Object collection) {
return bag==collection;
return bag == collection;
}
@Override
public boolean isDirectlyProvidedCollection(Object collection) {
return isDirectlyAccessible() && providedCollection == collection;
}
@Override

View File

@ -40,6 +40,9 @@ public class PersistentIdentifierBag extends AbstractPersistentCollection implem
protected List<Object> values;
protected Map<Integer, Object> identifiers;
// The Collection provided to a PersistentIdentifierBag constructor,
private Collection providedValues;
/**
* Constructs a PersistentIdentifierBag. This form needed for SOAP libraries, etc
*/
@ -76,6 +79,7 @@ public class PersistentIdentifierBag extends AbstractPersistentCollection implem
@SuppressWarnings("unchecked")
public PersistentIdentifierBag(SharedSessionContractImplementor session, Collection coll) {
super( session );
providedValues = coll;
if (coll instanceof List) {
values = (List<Object>) coll;
}
@ -124,7 +128,12 @@ public class PersistentIdentifierBag extends AbstractPersistentCollection implem
@Override
public boolean isWrapper(Object collection) {
return values==collection;
return values == collection;
}
@Override
public boolean isDirectlyProvidedCollection(Object collection) {
return isDirectlyAccessible() && providedValues == collection;
}
@Override

View File

@ -400,6 +400,21 @@ public interface PersistentCollection {
return false;
}
/**
* Was {@code collection} provided directly to this PersistentCollection
* (i.e., provided as an argument to a constructor)?
* <p/>
* Implementors that can copy elements out of a directly provided
* collection into the wrapped collection should override this method.
* <p/>
* @param collection The collection
* @return true, if {@code collection} was provided directly to this
* PersistentCollection; false, otherwise.
*/
default boolean isDirectlyProvidedCollection(Object collection) {
return isDirectlyAccessible() && isWrapper( collection );
}
/**
* Clear the dirty flag, after flushing changes
* to the database.

View File

@ -106,8 +106,12 @@ public abstract class CollectionType extends AbstractType implements Association
@Override
public final boolean isEqual(Object x, Object y) {
return x == y
|| ( x instanceof PersistentCollection && ( (PersistentCollection) x ).wasInitialized() && ( (PersistentCollection) x ).isWrapper( y ) )
|| ( y instanceof PersistentCollection && ( (PersistentCollection) y ).wasInitialized() && ( (PersistentCollection) y ).isWrapper( x ) );
|| ( x instanceof PersistentCollection && isEqual( (PersistentCollection) x, y ) )
|| ( y instanceof PersistentCollection && isEqual( (PersistentCollection) y, x ) );
}
private boolean isEqual(PersistentCollection x, Object y) {
return x.wasInitialized() && ( x.isWrapper( y ) || x.isDirectlyProvidedCollection( y ) );
}
@Override