use of org.hibernate.StaleObjectStateException in project hibernate-orm by hibernate.
the class DefaultMergeEventListener method entityIsDetached.
protected void entityIsDetached(MergeEvent event, Map copyCache) {
LOG.trace("Merging detached instance");
final Object entity = event.getEntity();
final EventSource source = event.getSession();
final EntityPersister persister = source.getEntityPersister(event.getEntityName(), entity);
final String entityName = persister.getEntityName();
Serializable id = event.getRequestedId();
if (id == null) {
id = persister.getIdentifier(entity, source);
} else {
// check that entity id = requestedId
Serializable entityId = persister.getIdentifier(entity, source);
if (!persister.getIdentifierType().isEqual(id, entityId, source.getFactory())) {
throw new HibernateException("merge requested with id not matching id of passed entity");
}
}
String previousFetchProfile = source.getLoadQueryInfluencers().getInternalFetchProfile();
source.getLoadQueryInfluencers().setInternalFetchProfile("merge");
//we must clone embedded composite identifiers, or
//we will get back the same instance that we pass in
final Serializable clonedIdentifier = (Serializable) persister.getIdentifierType().deepCopy(id, source.getFactory());
final Object result = source.get(entityName, clonedIdentifier);
source.getLoadQueryInfluencers().setInternalFetchProfile(previousFetchProfile);
if (result == null) {
//TODO: we should throw an exception if we really *know* for sure
// that this is a detached instance, rather than just assuming
//throw new StaleObjectStateException(entityName, id);
// we got here because we assumed that an instance
// with an assigned id was detached, when it was
// really persistent
entityIsTransient(event, copyCache);
} else {
//beforeQuery cascade!
((MergeContext) copyCache).put(entity, result, true);
final Object target = source.getPersistenceContext().unproxy(result);
if (target == entity) {
throw new AssertionFailure("entity was not detached");
} else if (!source.getEntityName(target).equals(entityName)) {
throw new WrongClassException("class of the given object did not match class of persistent copy", event.getRequestedId(), entityName);
} else if (isVersionChanged(entity, source, persister, target)) {
if (source.getFactory().getStatistics().isStatisticsEnabled()) {
source.getFactory().getStatisticsImplementor().optimisticFailure(entityName);
}
throw new StaleObjectStateException(entityName, id);
}
// cascade first, so that all unsaved objects get their
// copy created beforeQuery we actually copy
cascadeOnMerge(source, persister, entity, copyCache);
copyValues(persister, entity, target, source, copyCache);
//copyValues works by reflection, so explicitly mark the entity instance dirty
markInterceptorDirty(entity, target, persister);
event.setResult(result);
}
}
use of org.hibernate.StaleObjectStateException in project hibernate-orm by hibernate.
the class Loader method checkVersion.
/**
* Check the version of the object in the <tt>ResultSet</tt> against
* the object version in the session cache, throwing an exception
* if the version numbers are different
*/
private void checkVersion(final int i, final Loadable persister, final Serializable id, final Object entity, final ResultSet rs, final SharedSessionContractImplementor session) throws HibernateException, SQLException {
Object version = session.getPersistenceContext().getEntry(entity).getVersion();
if (version != null) {
//null version means the object is in the process of being loaded somewhere else in the ResultSet
final VersionType versionType = persister.getVersionType();
final Object currentVersion = versionType.nullSafeGet(rs, getEntityAliases()[i].getSuffixedVersionAliases(), session, null);
if (!versionType.isEqual(version, currentVersion)) {
if (session.getFactory().getStatistics().isStatisticsEnabled()) {
session.getFactory().getStatistics().optimisticFailure(persister.getEntityName());
}
throw new StaleObjectStateException(persister.getEntityName(), id);
}
}
}
use of org.hibernate.StaleObjectStateException in project hibernate-orm by hibernate.
the class OptimisticLockTest method testDeleteOptimisticLockFailure.
private void testDeleteOptimisticLockFailure(String entityName) {
Session mainSession = openSession();
mainSession.beginTransaction();
Document doc = new Document();
doc.setTitle("Hibernate in Action");
doc.setAuthor("Bauer et al");
doc.setSummary("Very boring book about persistence");
doc.setText("blah blah yada yada yada");
doc.setPubDate(new PublicationDate(2004));
mainSession.save(entityName, doc);
mainSession.flush();
doc.setSummary("A modern classic");
mainSession.flush();
doc.getPubDate().setMonth(Integer.valueOf(3));
mainSession.flush();
mainSession.getTransaction().commit();
mainSession.close();
mainSession = openSession();
mainSession.beginTransaction();
doc = (Document) mainSession.get(entityName, doc.getId());
Session otherSession = openSession();
otherSession.beginTransaction();
Document otherDoc = (Document) otherSession.get(entityName, doc.getId());
otherDoc.setSummary("my other summary");
otherSession.flush();
otherSession.getTransaction().commit();
otherSession.close();
try {
mainSession.delete(doc);
mainSession.flush();
fail("expecting opt lock failure");
} catch (StaleObjectStateException e) {
// expected
} catch (PersistenceException e) {
// expected
checkException(mainSession, e);
}
mainSession.clear();
mainSession.getTransaction().rollback();
mainSession.close();
mainSession = openSession();
mainSession.beginTransaction();
doc = (Document) mainSession.load(entityName, doc.getId());
mainSession.delete(entityName, doc);
mainSession.getTransaction().commit();
mainSession.close();
}
use of org.hibernate.StaleObjectStateException in project hibernate-orm by hibernate.
the class AbstractEntityPersister method forceVersionIncrement.
public Object forceVersionIncrement(Serializable id, Object currentVersion, SharedSessionContractImplementor session) {
if (!isVersioned()) {
throw new AssertionFailure("cannot force version increment on non-versioned entity");
}
if (isVersionPropertyGenerated()) {
// force the version to be incremented in the db...
throw new HibernateException("LockMode.FORCE is currently not supported for generated version properties");
}
Object nextVersion = getVersionType().next(currentVersion, session);
if (LOG.isTraceEnabled()) {
LOG.trace("Forcing version increment [" + MessageHelper.infoString(this, id, getFactory()) + "; " + getVersionType().toLoggableString(currentVersion, getFactory()) + " -> " + getVersionType().toLoggableString(nextVersion, getFactory()) + "]");
}
// todo : cache this sql...
String versionIncrementString = generateVersionIncrementUpdateString();
PreparedStatement st = null;
try {
st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement(versionIncrementString, false);
try {
getVersionType().nullSafeSet(st, nextVersion, 1, session);
getIdentifierType().nullSafeSet(st, id, 2, session);
getVersionType().nullSafeSet(st, currentVersion, 2 + getIdentifierColumnSpan(), session);
int rows = session.getJdbcCoordinator().getResultSetReturn().executeUpdate(st);
if (rows != 1) {
throw new StaleObjectStateException(getEntityName(), id);
}
} finally {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(st);
session.getJdbcCoordinator().afterStatementExecution();
}
} catch (SQLException sqle) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(sqle, "could not retrieve version: " + MessageHelper.infoString(this, id, getFactory()), getVersionSelectString());
}
return nextVersion;
}
use of org.hibernate.StaleObjectStateException in project hibernate-orm by hibernate.
the class EntityReferenceInitializerImpl method checkVersion.
private void checkVersion(SharedSessionContractImplementor session, ResultSet resultSet, EntityPersister persister, EntityAliases entityAliases, EntityKey entityKey, Object entityInstance) {
final Object version = session.getPersistenceContext().getEntry(entityInstance).getVersion();
if (version != null) {
//null version means the object is in the process of being loaded somewhere else in the ResultSet
VersionType versionType = persister.getVersionType();
final Object currentVersion;
try {
currentVersion = versionType.nullSafeGet(resultSet, entityAliases.getSuffixedVersionAliases(), session, null);
} catch (SQLException e) {
throw session.getFactory().getServiceRegistry().getService(JdbcServices.class).getSqlExceptionHelper().convert(e, "Could not read version value from result set");
}
if (!versionType.isEqual(version, currentVersion)) {
if (session.getFactory().getStatistics().isStatisticsEnabled()) {
session.getFactory().getStatistics().optimisticFailure(persister.getEntityName());
}
throw new StaleObjectStateException(persister.getEntityName(), entityKey.getIdentifier());
}
}
}
Aggregations