use of org.hibernate.WrongClassException in project hibernate-orm by hibernate.
the class PolymorphicCacheTest method testPolymorphismAndCache.
@Test
public void testPolymorphismAndCache() throws Exception {
final CachedItem1 item1 = new CachedItem1("name 1");
final CachedItem2 item2 = new CachedItem2("name 2");
// create the 2 items
Session s = openSession();
s.beginTransaction();
s.save(item1);
s.save(item2);
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
// See HHH-9107
try {
final CachedItem2 tmp = s.get(CachedItem2.class, item1.getId());
fail("Expected a WrongClassException to be thrown.");
} catch (WrongClassException e) {
// expected
}
s.getTransaction().commit();
s.close();
// test updating
s = openSession();
s.beginTransaction();
item1.setName("updated");
s.update(item1);
s.getTransaction().commit();
s.clear();
s.beginTransaction();
CachedItem1 cachedItem1 = (CachedItem1) s.get(CachedItem1.class, item1.getId());
CachedItem2 cachedItem2 = (CachedItem2) s.get(CachedItem2.class, item2.getId());
assertEquals("updated", cachedItem1.getName());
assertEquals(item2.getName(), cachedItem2.getName());
s.getTransaction().commit();
s.close();
// test deleting
s = openSession();
s.beginTransaction();
s.delete(item1);
s.getTransaction().commit();
s.clear();
s.beginTransaction();
cachedItem1 = (CachedItem1) s.get(CachedItem1.class, item1.getId());
cachedItem2 = (CachedItem2) s.get(CachedItem2.class, item2.getId());
assertNull(cachedItem1);
assertNotNull(cachedItem2);
assertEquals(item2.getName(), cachedItem2.getName());
s.getTransaction().commit();
s.close();
// cleanup
s = openSession();
s.beginTransaction();
s.createQuery("DELETE FROM AbstractCachedItem").executeUpdate();
s.getTransaction().commit();
s.close();
}
use of org.hibernate.WrongClassException in project hibernate-orm by hibernate.
the class EntityReferenceInitializerImpl method hydrateEntityState.
@Override
public void hydrateEntityState(ResultSet resultSet, ResultSetProcessingContextImpl context) {
final EntityReferenceProcessingState processingState = context.getProcessingState(entityReference);
// If there is no identifier for this entity reference for this row, nothing to do
if (processingState.isMissingIdentifier()) {
handleMissingIdentifier(context);
return;
}
// make sure we have the EntityKey
final EntityKey entityKey = processingState.getEntityKey();
if (entityKey == null) {
handleMissingIdentifier(context);
return;
}
// Have we already hydrated this entity's state?
if (processingState.getEntityInstance() != null) {
return;
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// In getting here, we know that:
// 1) We need to hydrate the entity state
// 2) We have a valid EntityKey for the entity
// see if we have an existing entry in the session for this EntityKey
final Object existing = context.getSession().getEntityUsingInterceptor(entityKey);
if (existing != null) {
// It is previously associated with the Session, perform some checks
if (!entityReference.getEntityPersister().isInstance(existing)) {
throw new WrongClassException("loaded object was of wrong class " + existing.getClass(), entityKey.getIdentifier(), entityReference.getEntityPersister().getEntityName());
}
checkVersion(resultSet, context, entityKey, existing);
// use the existing association as the hydrated state
processingState.registerEntityInstance(existing);
// context.registerHydratedEntity( entityReference, entityKey, existing );
return;
}
// Otherwise, we need to load it from the ResultSet...
// determine which entity instance to use. Either the supplied one, or instantiate one
Object entityInstance = null;
if (isReturn && context.shouldUseOptionalEntityInformation() && context.getQueryParameters().getOptionalObject() != null) {
final EntityKey optionalEntityKey = ResultSetProcessorHelper.getOptionalObjectKey(context.getQueryParameters(), context.getSession());
if (optionalEntityKey != null && optionalEntityKey.equals(entityKey)) {
entityInstance = context.getQueryParameters().getOptionalObject();
}
}
final String concreteEntityTypeName = getConcreteEntityTypeName(resultSet, context, entityKey);
if (entityInstance == null) {
entityInstance = context.getSession().instantiate(concreteEntityTypeName, entityKey.getIdentifier());
}
processingState.registerEntityInstance(entityInstance);
// need to hydrate it.
// grab its state from the ResultSet and keep it in the Session
// (but don't yet initialize the object itself)
// note that we acquire LockMode.READ even if it was not requested
log.trace("hydrating entity state");
final LockMode requestedLockMode = context.resolveLockMode(entityReference);
final LockMode lockModeToAcquire = requestedLockMode == LockMode.NONE ? LockMode.READ : requestedLockMode;
loadFromResultSet(resultSet, context, entityInstance, concreteEntityTypeName, entityKey, lockModeToAcquire);
}
use of org.hibernate.WrongClassException 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 {
// before 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().getStatistics().optimisticFailure(entityName);
}
throw new StaleObjectStateException(entityName, id);
}
// cascade first, so that all unsaved objects get their
// copy created before 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.WrongClassException in project hibernate-orm by hibernate.
the class EntityReferenceInitializerImpl method getConcreteEntityTypeName.
private String getConcreteEntityTypeName(ResultSet resultSet, ResultSetProcessingContext context, EntityKey entityKey) {
final Loadable loadable = (Loadable) entityReference.getEntityPersister();
if (!loadable.hasSubclasses()) {
return entityReference.getEntityPersister().getEntityName();
}
final Object discriminatorValue;
try {
discriminatorValue = loadable.getDiscriminatorType().nullSafeGet(resultSet, entityReferenceAliases.getColumnAliases().getSuffixedDiscriminatorAlias(), context.getSession(), null);
} catch (SQLException e) {
throw context.getSession().getFactory().getServiceRegistry().getService(JdbcServices.class).getSqlExceptionHelper().convert(e, "Could not read discriminator value from ResultSet");
}
final String result = loadable.getSubclassForDiscriminatorValue(discriminatorValue);
if (result == null) {
// whoops! we got an instance of another class hierarchy branch
throw new WrongClassException("Discriminator: " + discriminatorValue, entityKey.getIdentifier(), entityReference.getEntityPersister().getEntityName());
}
return result;
}
Aggregations