use of org.hibernate.collection.spi.PersistentCollection in project hibernate-orm by hibernate.
the class OnLockVisitor method processCollection.
@Override
public Object processCollection(Object collection, CollectionType type) throws HibernateException {
if (collection == null) {
return null;
}
final SessionImplementor session = getSession();
final CollectionPersister persister = session.getFactory().getCollectionPersister(type.getRole());
if (collection instanceof PersistentCollection) {
final PersistentCollection persistentCollection = (PersistentCollection) collection;
if (persistentCollection.setCurrentSession(session)) {
if (isOwnerUnchanged(persistentCollection, persister, extractCollectionKeyFromOwner(persister))) {
// a "detached" collection that originally belonged to the same entity
if (persistentCollection.isDirty()) {
throw new HibernateException("reassociated object has dirty collection");
}
reattachCollection(persistentCollection, type);
} else {
// a "detached" collection that belonged to a different entity
throw new HibernateException("reassociated object has dirty collection reference");
}
} else {
// to the entity passed to update()
throw new HibernateException("reassociated object has dirty collection reference");
}
} else {
//TODO: or an array!! we can't lock objects with arrays now??
throw new HibernateException("reassociated object has dirty collection reference (or an array)");
}
return null;
}
use of org.hibernate.collection.spi.PersistentCollection in project hibernate-orm by hibernate.
the class Loader method readCollectionElement.
/**
* Read one collection element from the current row of the JDBC result set
*/
private void readCollectionElement(final Object optionalOwner, final Serializable optionalKey, final CollectionPersister persister, final CollectionAliases descriptor, final ResultSet rs, final SharedSessionContractImplementor session) throws HibernateException, SQLException {
final PersistenceContext persistenceContext = session.getPersistenceContext();
final Serializable collectionRowKey = (Serializable) persister.readKey(rs, descriptor.getSuffixedKeyAliases(), session);
if (collectionRowKey != null) {
if (LOG.isDebugEnabled()) {
LOG.debugf("Found row of collection: %s", MessageHelper.collectionInfoString(persister, collectionRowKey, getFactory()));
}
Object owner = optionalOwner;
if (owner == null) {
owner = persistenceContext.getCollectionOwner(collectionRowKey, persister);
if (owner == null) {
//TODO: This is assertion is disabled because there is a bug that means the
// original owner of a transient, uninitialized collection is not known
// if the collection is re-referenced by a different object associated
// with the current Session
//throw new AssertionFailure("bug loading unowned collection");
}
}
PersistentCollection rowCollection = persistenceContext.getLoadContexts().getCollectionLoadContext(rs).getLoadingCollection(persister, collectionRowKey);
if (rowCollection != null) {
rowCollection.readFrom(rs, persister, descriptor, owner);
}
} else if (optionalKey != null) {
if (LOG.isDebugEnabled()) {
LOG.debugf("Result set contains (possibly empty) collection: %s", MessageHelper.collectionInfoString(persister, optionalKey, getFactory()));
}
persistenceContext.getLoadContexts().getCollectionLoadContext(rs).getLoadingCollection(persister, // handle empty collection
optionalKey);
}
// else no collection element, but also no owner
}
use of org.hibernate.collection.spi.PersistentCollection in project hibernate-orm by hibernate.
the class CollectionReferenceInitializerImpl method finishUpRow.
@Override
public void finishUpRow(ResultSet resultSet, ResultSetProcessingContextImpl context) {
try {
// read the collection key for this reference for the current row.
final PersistenceContext persistenceContext = context.getSession().getPersistenceContext();
final Serializable collectionRowKey = (Serializable) collectionReference.getCollectionPersister().readKey(resultSet, aliases.getCollectionColumnAliases().getSuffixedKeyAliases(), context.getSession());
if (collectionRowKey != null) {
if (log.isDebugEnabled()) {
log.debugf("Found row of collection: %s", MessageHelper.collectionInfoString(collectionReference.getCollectionPersister(), collectionRowKey, context.getSession().getFactory()));
}
Object collectionOwner = findCollectionOwner(collectionRowKey, resultSet, context);
PersistentCollection rowCollection = persistenceContext.getLoadContexts().getCollectionLoadContext(resultSet).getLoadingCollection(collectionReference.getCollectionPersister(), collectionRowKey);
if (rowCollection != null) {
rowCollection.readFrom(resultSet, collectionReference.getCollectionPersister(), aliases.getCollectionColumnAliases(), collectionOwner);
}
} else {
final Serializable optionalKey = findCollectionOwnerKey(context);
if (optionalKey != null) {
// since what we have is an empty collection
if (log.isDebugEnabled()) {
log.debugf("Result set contains (possibly empty) collection: %s", MessageHelper.collectionInfoString(collectionReference.getCollectionPersister(), optionalKey, context.getSession().getFactory()));
}
// handle empty collection
persistenceContext.getLoadContexts().getCollectionLoadContext(resultSet).getLoadingCollection(collectionReference.getCollectionPersister(), optionalKey);
}
}
// else no collection element, but also no owner
} catch (SQLException sqle) {
// TODO: would be nice to have the SQL string that failed...
throw context.getSession().getFactory().getSQLExceptionHelper().convert(sqle, "could not read next row of results");
}
}
use of org.hibernate.collection.spi.PersistentCollection in project hibernate-orm by hibernate.
the class CollectionType method replaceElements.
/**
* Replace the elements of a collection with the elements of another collection.
*
* @param original The 'source' of the replacement elements (where we copy from)
* @param target The target of the replacement elements (where we copy to)
* @param owner The owner of the collection being merged
* @param copyCache The map of elements already replaced.
* @param session The session from which the merge event originated.
* @return The merged collection.
*/
public Object replaceElements(Object original, Object target, Object owner, Map copyCache, SharedSessionContractImplementor session) {
// TODO: does not work for EntityMode.DOM4J yet!
java.util.Collection result = (java.util.Collection) target;
result.clear();
// copy elements into newly empty target collection
Type elemType = getElementType(session.getFactory());
Iterator iter = ((java.util.Collection) original).iterator();
while (iter.hasNext()) {
result.add(elemType.replace(iter.next(), null, session, owner, copyCache));
}
// on the target because we simply do not know...
if (original instanceof PersistentCollection) {
if (result instanceof PersistentCollection) {
final PersistentCollection originalPersistentCollection = (PersistentCollection) original;
final PersistentCollection resultPersistentCollection = (PersistentCollection) result;
preserveSnapshot(originalPersistentCollection, resultPersistentCollection, elemType, owner, copyCache, session);
if (!originalPersistentCollection.isDirty()) {
resultPersistentCollection.clearDirty();
}
}
}
return result;
}
use of org.hibernate.collection.spi.PersistentCollection in project hibernate-orm by hibernate.
the class CollectionType method replace.
@Override
public Object replace(final Object original, final Object target, final SharedSessionContractImplementor session, final Object owner, final Map copyCache) throws HibernateException {
if (original == null) {
return null;
}
if (!Hibernate.isInitialized(original)) {
if (((PersistentCollection) original).hasQueuedOperations()) {
final AbstractPersistentCollection pc = (AbstractPersistentCollection) original;
pc.replaceQueuedOperationValues(getPersister(session), copyCache);
}
return target;
}
// for a null target, or a target which is the same as the original, we
// need to put the merged elements in a new collection
Object result = target == null || target == original ? instantiateResult(original) : target;
//for arrays, replaceElements() may return a different reference, since
//the array length might not match
result = replaceElements(original, result, owner, copyCache, session);
if (original == target) {
// get the elements back into the target making sure to handle dirty flag
boolean wasClean = PersistentCollection.class.isInstance(target) && !((PersistentCollection) target).isDirty();
//TODO: this is a little inefficient, don't need to do a whole
// deep replaceElements() call
replaceElements(result, target, owner, copyCache, session);
if (wasClean) {
((PersistentCollection) target).clearDirty();
}
result = target;
}
return result;
}
Aggregations