use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class DefaultMergeEventListener method existsInDatabase.
private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
EntityEntry entry = source.getPersistenceContext().getEntry(entity);
if (entry == null) {
Serializable id = persister.getIdentifier(entity, source);
if (id != null) {
final EntityKey key = source.generateEntityKey(id, persister);
final Object managedEntity = source.getPersistenceContext().getEntity(key);
entry = source.getPersistenceContext().getEntry(managedEntity);
}
}
return entry != null && entry.isExistsInDatabase();
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class DefaultMergeEventListener method onMerge.
/**
* Handle the given merge event.
*
* @param event The merge event to be handled.
*
* @throws HibernateException
*/
public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException {
final MergeContext copyCache = (MergeContext) copiedAlready;
final EventSource source = event.getSession();
final Object original = event.getOriginal();
if (original != null) {
final Object entity;
if (original instanceof HibernateProxy) {
LazyInitializer li = ((HibernateProxy) original).getHibernateLazyInitializer();
if (li.isUninitialized()) {
LOG.trace("Ignoring uninitialized proxy");
event.setResult(source.load(li.getEntityName(), li.getIdentifier()));
//EARLY EXIT!
return;
} else {
entity = li.getImplementation();
}
} else {
entity = original;
}
if (copyCache.containsKey(entity) && (copyCache.isOperatedOn(entity))) {
LOG.trace("Already in merge process");
event.setResult(entity);
} else {
if (copyCache.containsKey(entity)) {
LOG.trace("Already in copyCache; setting in merge process");
copyCache.setOperatedOn(entity, true);
}
event.setEntity(entity);
EntityState entityState = null;
// Check the persistence context for an entry relating to this
// entity to be merged...
EntityEntry entry = source.getPersistenceContext().getEntry(entity);
if (entry == null) {
EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
Serializable id = persister.getIdentifier(entity, source);
if (id != null) {
final EntityKey key = source.generateEntityKey(id, persister);
final Object managedEntity = source.getPersistenceContext().getEntity(key);
entry = source.getPersistenceContext().getEntry(managedEntity);
if (entry != null) {
// we have specialized case of a detached entity from the
// perspective of the merge operation. Specifically, we
// have an incoming entity instance which has a corresponding
// entry in the current persistence context, but registered
// under a different entity instance
entityState = EntityState.DETACHED;
}
}
}
if (entityState == null) {
entityState = getEntityState(entity, event.getEntityName(), entry, source);
}
switch(entityState) {
case DETACHED:
entityIsDetached(event, copyCache);
break;
case TRANSIENT:
entityIsTransient(event, copyCache);
break;
case PERSISTENT:
entityIsPersistent(event, copyCache);
break;
default:
//DELETED
throw new ObjectDeletedException("deleted instance passed to merge", null, getLoggableName(event.getEntityName(), entity));
}
}
}
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class DefaultRefreshEventListener method onRefresh.
/**
* Handle the given refresh event.
*
* @param event The refresh event to be handled.
*/
public void onRefresh(RefreshEvent event, Map refreshedAlready) {
final EventSource source = event.getSession();
boolean isTransient;
if (event.getEntityName() != null) {
isTransient = !source.contains(event.getEntityName(), event.getObject());
} else {
isTransient = !source.contains(event.getObject());
}
if (source.getPersistenceContext().reassociateIfUninitializedProxy(event.getObject())) {
if (isTransient) {
source.setReadOnly(event.getObject(), source.isDefaultReadOnly());
}
return;
}
final Object object = source.getPersistenceContext().unproxyAndReassociate(event.getObject());
if (refreshedAlready.containsKey(object)) {
LOG.trace("Already refreshed");
return;
}
final EntityEntry e = source.getPersistenceContext().getEntry(object);
final EntityPersister persister;
final Serializable id;
if (e == null) {
persister = source.getEntityPersister(event.getEntityName(), object);
//refresh() does not pass an entityName
id = persister.getIdentifier(object, event.getSession());
if (LOG.isTraceEnabled()) {
LOG.tracev("Refreshing transient {0}", MessageHelper.infoString(persister, id, source.getFactory()));
}
final EntityKey key = source.generateEntityKey(id, persister);
if (source.getPersistenceContext().getEntry(key) != null) {
throw new PersistentObjectException("attempted to refresh transient instance when persistent instance was already associated with the Session: " + MessageHelper.infoString(persister, id, source.getFactory()));
}
} else {
if (LOG.isTraceEnabled()) {
LOG.tracev("Refreshing ", MessageHelper.infoString(e.getPersister(), e.getId(), source.getFactory()));
}
if (!e.isExistsInDatabase()) {
throw new UnresolvableObjectException(e.getId(), "this instance does not yet exist as a row in the database");
}
persister = e.getPersister();
id = e.getId();
}
// cascade the refresh prior to refreshing this entity
refreshedAlready.put(object, object);
Cascade.cascade(CascadingActions.REFRESH, CascadePoint.BEFORE_REFRESH, source, persister, object, refreshedAlready);
if (e != null) {
final EntityKey key = source.generateEntityKey(id, persister);
source.getPersistenceContext().removeEntity(key);
if (persister.hasCollections()) {
new EvictVisitor(source).process(object, persister);
}
}
if (persister.hasCache()) {
Object previousVersion = null;
if (persister.isVersionPropertyGenerated()) {
// we need to grab the version value from the entity, otherwise
// we have issues with generated-version entities that may have
// multiple actions queued during the same flush
previousVersion = persister.getVersion(object);
}
final EntityRegionAccessStrategy cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(id, persister, source.getFactory(), source.getTenantIdentifier());
final SoftLock lock = cache.lockItem(source, ck, previousVersion);
source.getActionQueue().registerProcess(new AfterTransactionCompletionProcess() {
@Override
public void doAfterTransactionCompletion(boolean success, SharedSessionContractImplementor session) {
cache.unlockItem(session, ck, lock);
}
});
cache.remove(source, ck);
}
evictCachedCollections(persister, id, source);
String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
source.getLoadQueryInfluencers().setInternalFetchProfile("refresh");
Object result = persister.load(id, object, event.getLockOptions(), source);
// If it was transient, then set it to the default for the source.
if (result != null) {
if (!persister.isMutable()) {
// this is probably redundant; it should already be read-only
source.setReadOnly(result, true);
} else {
source.setReadOnly(result, (e == null ? source.isDefaultReadOnly() : e.isReadOnly()));
}
}
source.getLoadQueryInfluencers().setInternalFetchProfile(previousFetchProfile);
UnresolvableObjectException.throwIfNull(result, id, persister.getEntityName());
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class DefaultReplicateEventListener method onReplicate.
/**
* Handle the given replicate event.
*
* @param event The replicate event to be handled.
*
* @throws TransientObjectException An invalid attempt to replicate a transient entity.
*/
public void onReplicate(ReplicateEvent event) {
final EventSource source = event.getSession();
if (source.getPersistenceContext().reassociateIfUninitializedProxy(event.getObject())) {
LOG.trace("Uninitialized proxy passed to replicate()");
return;
}
Object entity = source.getPersistenceContext().unproxyAndReassociate(event.getObject());
if (source.getPersistenceContext().isEntryFor(entity)) {
LOG.trace("Ignoring persistent instance passed to replicate()");
//hum ... should we cascade anyway? throw an exception? fine like it is?
return;
}
EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
// get the id from the object
/*if ( persister.isUnsaved(entity, source) ) {
throw new TransientObjectException("transient instance passed to replicate()");
}*/
Serializable id = persister.getIdentifier(entity, source);
if (id == null) {
throw new TransientObjectException("instance with null id passed to replicate()");
}
final ReplicationMode replicationMode = event.getReplicationMode();
final Object oldVersion;
if (replicationMode == ReplicationMode.EXCEPTION) {
//always do an INSERT, and let it fail by constraint violation
oldVersion = null;
} else {
//what is the version on the database?
oldVersion = persister.getCurrentVersion(id, source);
}
final boolean traceEnabled = LOG.isTraceEnabled();
if (oldVersion != null) {
if (traceEnabled) {
LOG.tracev("Found existing row for {0}", MessageHelper.infoString(persister, id, source.getFactory()));
}
/// HHH-2378
final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(entity, realOldVersion, persister.getVersion(entity), persister.getVersionType());
// else do nothing (don't even reassociate object!)
if (canReplicate) {
performReplication(entity, id, realOldVersion, persister, replicationMode, source);
} else if (traceEnabled) {
LOG.trace("No need to replicate");
}
//TODO: would it be better to do a refresh from db?
} else {
// no existing row - do an insert
if (traceEnabled) {
LOG.tracev("No existing row, replicating new instance {0}", MessageHelper.infoString(persister, id, source.getFactory()));
}
// prefer re-generation of identity!
final boolean regenerate = persister.isIdentifierAssignedByInsert();
final EntityKey key = regenerate ? null : source.generateEntityKey(id, persister);
performSaveOrReplicate(entity, key, persister, regenerate, replicationMode, source, true);
}
}
use of org.hibernate.engine.spi.EntityKey in project hibernate-orm by hibernate.
the class DefaultLoadEventListener method loadByDerivedIdentitySimplePkValue.
private void loadByDerivedIdentitySimplePkValue(LoadEvent event, LoadEventListener.LoadType options, EntityPersister dependentPersister, EmbeddedComponentType dependentIdType, EntityPersister parentPersister) {
final EntityKey parentEntityKey = event.getSession().generateEntityKey(event.getEntityId(), parentPersister);
final Object parent = doLoad(event, parentPersister, parentEntityKey, options);
final Serializable dependent = (Serializable) dependentIdType.instantiate(parent, event.getSession());
dependentIdType.setPropertyValues(dependent, new Object[] { parent }, dependentPersister.getEntityMode());
final EntityKey dependentEntityKey = event.getSession().generateEntityKey(dependent, dependentPersister);
event.setEntityId(dependent);
event.setResult(doLoad(event, dependentPersister, dependentEntityKey, options));
}
Aggregations