use of org.hibernate.PersistentObjectException in project hibernate-orm by hibernate.
the class DefaultLoadEventListener method load.
/**
* Performs the load of an entity.
*
* @param event The initiating load request event
* @param persister The persister corresponding to the entity to be loaded
* @param keyToLoad The key of the entity to be loaded
* @param options The defined load options
*
* @return The loaded entity.
*
* @throws HibernateException
*/
private Object load(final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options) {
if (event.getInstanceToLoad() != null) {
if (event.getSession().getPersistenceContext().getEntry(event.getInstanceToLoad()) != null) {
throw new PersistentObjectException("attempted to load into an instance that was already associated with the session: " + MessageHelper.infoString(persister, event.getEntityId(), event.getSession().getFactory()));
}
persister.setIdentifier(event.getInstanceToLoad(), event.getEntityId(), event.getSession());
}
final Object entity = doLoad(event, persister, keyToLoad, options);
boolean isOptionalInstance = event.getInstanceToLoad() != null;
if (entity == null && (!options.isAllowNulls() || isOptionalInstance)) {
event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound(event.getEntityClassName(), event.getEntityId());
} else if (isOptionalInstance && entity != event.getInstanceToLoad()) {
throw new NonUniqueObjectException(event.getEntityId(), event.getEntityClassName());
}
return entity;
}
use of org.hibernate.PersistentObjectException 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, object).process(object, persister);
}
}
if (persister.canWriteToCache()) {
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 EntityDataAccess cache = persister.getCacheAccessStrategy();
final Object ck = cache.generateCacheKey(id, persister, source.getFactory(), source.getTenantIdentifier());
final SoftLock lock = cache.lockItem(source, ck, previousVersion);
cache.remove(source, ck);
source.getActionQueue().registerProcess((success, session) -> cache.unlockItem(session, ck, lock));
}
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.PersistentObjectException in project hibernate-orm by hibernate.
the class DefaultSaveOrUpdateEventListener method entityIsPersistent.
protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {
final boolean traceEnabled = LOG.isTraceEnabled();
if (traceEnabled) {
LOG.trace("Ignoring persistent instance");
}
EntityEntry entityEntry = event.getEntry();
if (entityEntry == null) {
throw new AssertionFailure("entity was transient or detached");
} else {
if (entityEntry.getStatus() == Status.DELETED) {
throw new AssertionFailure("entity was deleted");
}
final SessionFactoryImplementor factory = event.getSession().getFactory();
Serializable requestedId = event.getRequestedId();
Serializable savedId;
if (requestedId == null) {
savedId = entityEntry.getId();
} else {
final boolean isEqual = !entityEntry.getPersister().getIdentifierType().isEqual(requestedId, entityEntry.getId(), factory);
if (isEqual) {
throw new PersistentObjectException("object passed to save() was already persistent: " + MessageHelper.infoString(entityEntry.getPersister(), requestedId, factory));
}
savedId = requestedId;
}
if (traceEnabled) {
LOG.tracev("Object already associated with session: {0}", MessageHelper.infoString(entityEntry.getPersister(), savedId, factory));
}
return savedId;
}
}
use of org.hibernate.PersistentObjectException in project hibernate-orm by hibernate.
the class StatefulPersistenceContext method unproxy.
@Override
public Object unproxy(Object maybeProxy) throws HibernateException {
if (maybeProxy instanceof HibernateProxy) {
final HibernateProxy proxy = (HibernateProxy) maybeProxy;
final LazyInitializer li = proxy.getHibernateLazyInitializer();
if (li.isUninitialized()) {
throw new PersistentObjectException("object was an uninitialized proxy for " + li.getEntityName());
}
// unwrap the object and return
return li.getImplementation();
} else {
return maybeProxy;
}
}
use of org.hibernate.PersistentObjectException in project hibernate-orm by hibernate.
the class DefaultPersistEventListener method onPersist.
/**
* Handle the given create event.
*
* @param event The create event to be handled.
*/
public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
final SessionImplementor source = event.getSession();
final Object object = event.getObject();
final Object entity;
if (object instanceof HibernateProxy) {
LazyInitializer li = ((HibernateProxy) object).getHibernateLazyInitializer();
if (li.isUninitialized()) {
if (li.getSession() == source) {
// NOTE EARLY EXIT!
return;
} else {
throw new PersistentObjectException("uninitialized proxy passed to persist()");
}
}
entity = li.getImplementation();
} else {
entity = object;
}
final String entityName;
if (event.getEntityName() != null) {
entityName = event.getEntityName();
} else {
entityName = source.bestGuessEntityName(entity);
event.setEntityName(entityName);
}
final EntityEntry entityEntry = source.getPersistenceContext().getEntry(entity);
EntityState entityState = getEntityState(entity, entityName, entityEntry, source);
if (entityState == EntityState.DETACHED) {
// JPA 2, in its version of a "foreign generated", allows the id attribute value
// to be manually set by the user, even though this manual value is irrelevant.
// The issue is that this causes problems with the Hibernate unsaved-value strategy
// which comes into play here in determining detached/transient state.
//
// Detect if we have this situation and if so null out the id value and calculate the
// entity state again.
// NOTE: entityEntry must be null to get here, so we cannot use any of its values
EntityPersister persister = source.getFactory().getEntityPersister(entityName);
if (ForeignGenerator.class.isInstance(persister.getIdentifierGenerator())) {
if (LOG.isDebugEnabled() && persister.getIdentifier(entity, source) != null) {
LOG.debug("Resetting entity id attribute to null for foreign generator");
}
persister.setIdentifier(entity, null, source);
entityState = getEntityState(entity, entityName, entityEntry, source);
}
}
switch(entityState) {
case DETACHED:
{
throw new PersistentObjectException("detached entity passed to persist: " + getLoggableName(event.getEntityName(), entity));
}
case PERSISTENT:
{
entityIsPersistent(event, createCache);
break;
}
case TRANSIENT:
{
entityIsTransient(event, createCache);
break;
}
case DELETED:
{
entityEntry.setStatus(Status.MANAGED);
entityEntry.setDeletedState(null);
event.getSession().getActionQueue().unScheduleDeletion(entityEntry, event.getObject());
entityIsDeleted(event, createCache);
break;
}
default:
{
throw new ObjectDeletedException("deleted entity passed to persist", null, getLoggableName(event.getEntityName(), entity));
}
}
}
Aggregations