Search in sources :

Example 1 with WrongClassException

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();
}
Also used : WrongClassException(org.hibernate.WrongClassException) Session(org.hibernate.Session) Test(org.junit.Test)

Example 2 with WrongClassException

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);
}
Also used : EntityKey(org.hibernate.engine.spi.EntityKey) EntityReferenceProcessingState(org.hibernate.loader.plan.exec.process.spi.ResultSetProcessingContext.EntityReferenceProcessingState) LockMode(org.hibernate.LockMode) WrongClassException(org.hibernate.WrongClassException)

Example 3 with WrongClassException

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);
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) EventSource(org.hibernate.event.spi.EventSource) Serializable(java.io.Serializable) AssertionFailure(org.hibernate.AssertionFailure) HibernateException(org.hibernate.HibernateException) WrongClassException(org.hibernate.WrongClassException) StaleObjectStateException(org.hibernate.StaleObjectStateException)

Example 4 with WrongClassException

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;
}
Also used : UniqueKeyLoadable(org.hibernate.persister.entity.UniqueKeyLoadable) Loadable(org.hibernate.persister.entity.Loadable) SQLException(java.sql.SQLException) JdbcServices(org.hibernate.engine.jdbc.spi.JdbcServices) WrongClassException(org.hibernate.WrongClassException)

Aggregations

WrongClassException (org.hibernate.WrongClassException)4 Serializable (java.io.Serializable)1 SQLException (java.sql.SQLException)1 AssertionFailure (org.hibernate.AssertionFailure)1 HibernateException (org.hibernate.HibernateException)1 LockMode (org.hibernate.LockMode)1 Session (org.hibernate.Session)1 StaleObjectStateException (org.hibernate.StaleObjectStateException)1 JdbcServices (org.hibernate.engine.jdbc.spi.JdbcServices)1 EntityKey (org.hibernate.engine.spi.EntityKey)1 EventSource (org.hibernate.event.spi.EventSource)1 EntityReferenceProcessingState (org.hibernate.loader.plan.exec.process.spi.ResultSetProcessingContext.EntityReferenceProcessingState)1 EntityPersister (org.hibernate.persister.entity.EntityPersister)1 Loadable (org.hibernate.persister.entity.Loadable)1 UniqueKeyLoadable (org.hibernate.persister.entity.UniqueKeyLoadable)1 Test (org.junit.Test)1