use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class EntityUpdateAction method execute.
@Override
public void execute() throws HibernateException {
final Serializable id = getId();
final EntityPersister persister = getPersister();
final SharedSessionContractImplementor session = getSession();
final Object instance = getInstance();
final boolean veto = preUpdate();
final SessionFactoryImplementor factory = session.getFactory();
Object previousVersion = this.previousVersion;
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(instance);
}
final Object ck;
if (persister.canWriteToCache()) {
final EntityDataAccess cache = persister.getCacheAccessStrategy();
ck = cache.generateCacheKey(id, persister, factory, session.getTenantIdentifier());
lock = cache.lockItem(session, ck, previousVersion);
} else {
ck = null;
}
if (!veto) {
persister.update(id, state, dirtyFields, hasDirtyCollection, previousState, previousVersion, instance, rowId, session);
}
final EntityEntry entry = session.getPersistenceContext().getEntry(instance);
if (entry == null) {
throw new AssertionFailure("possible nonthreadsafe access to session");
}
if (entry.getStatus() == Status.MANAGED || persister.isVersionPropertyGenerated()) {
// get the updated snapshot of the entity state by cloning current state;
// it is safe to copy in place, since by this time no-one else (should have)
// has a reference to the array
TypeHelper.deepCopy(state, persister.getPropertyTypes(), persister.getPropertyCheckability(), state, session);
if (persister.hasUpdateGeneratedProperties()) {
// this entity defines proeprty generation, so process those generated
// values...
persister.processUpdateGeneratedProperties(id, instance, state, session);
if (persister.isVersionPropertyGenerated()) {
nextVersion = Versioning.getVersion(state, persister);
}
}
// have the entity entry doAfterTransactionCompletion post-update processing, passing it the
// update state and the new version (if one).
entry.postUpdate(instance, state, nextVersion);
}
if (persister.canWriteToCache()) {
if (persister.isCacheInvalidationRequired() || entry.getStatus() != Status.MANAGED) {
persister.getCacheAccessStrategy().remove(session, ck);
} else if (session.getCacheMode().isPutEnabled()) {
// TODO: inefficient if that cache is just going to ignore the updated state!
final CacheEntry ce = persister.buildCacheEntry(instance, state, nextVersion, getSession());
cacheEntry = persister.getCacheEntryStructure().structure(ce);
final boolean put = cacheUpdate(persister, previousVersion, ck);
if (put && factory.getStatistics().isStatisticsEnabled()) {
factory.getStatistics().entityCachePut(StatsHelper.INSTANCE.getRootEntityRole(persister), getPersister().getCacheAccessStrategy().getRegion().getName());
}
}
}
session.getPersistenceContext().getNaturalIdHelper().manageSharedNaturalIdCrossReference(persister, id, state, previousNaturalIdValues, CachedNaturalIdValueSource.UPDATE);
postUpdate();
if (factory.getStatistics().isStatisticsEnabled() && !veto) {
factory.getStatistics().updateEntity(getPersister().getEntityName());
}
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class UnionSubclassTest method testBulkOperationsWithDifferentConnections.
@Test
@TestForIssue(jiraKey = "HHH-11740")
public void testBulkOperationsWithDifferentConnections() throws Exception {
doInHibernate(this::sessionFactory, s -> {
Location mars = new Location("Mars");
s.persist(mars);
Location earth = new Location("Earth");
s.persist(earth);
Hive hive = new Hive();
hive.setLocation(mars);
s.persist(hive);
Alien alien = new Alien();
alien.setIdentity("Uncle Martin");
alien.setSpecies("Martian");
alien.setHive(hive);
hive.getMembers().add(alien);
mars.addBeing(alien);
s.persist(alien);
Human human = new Human();
human.setIdentity("Jane Doe");
human.setSex('M');
earth.addBeing(human);
s.persist(human);
});
// The following tests that bulk operations can be executed using 2 different
// connections.
doInHibernate(this::sessionFactory, s1 -> {
// Transaction used by s1 is already started.
// Assert that the Connection is already physically connected.
SharedSessionContractImplementor s1Implementor = (SharedSessionContractImplementor) s1;
assertTrue(s1Implementor.getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected());
// Assert that the same Connection will be used for s1's entire transaction
assertEquals(PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION, s1Implementor.getJdbcCoordinator().getLogicalConnection().getConnectionHandlingMode());
// Get the Connection s1 will use.
final Connection connection1 = s1Implementor.connection();
// Avoid a pessimistic lock exception by not doing anything with s1 until
// after a second Session (with a different connection) is used
// for a bulk operation.
doInHibernate(this::sessionFactory, s2 -> {
// Check same assertions for s2 as was done for s1.
SharedSessionContractImplementor s2Implementor = (SharedSessionContractImplementor) s2;
assertTrue(s2Implementor.getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected());
assertEquals(PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION, s2Implementor.getJdbcCoordinator().getLogicalConnection().getConnectionHandlingMode());
// Get the Connection s2 will use.
Connection connection2 = s2Implementor.connection();
// Assert that connection2 is not the same as connection1
assertNotSame(connection1, connection2);
// Execute a bulk operation on s2 (using connection2)
assertEquals(1, s2.createQuery("delete from Being where species = 'Martian'").executeUpdate());
// Assert the Connection has not changed
assertSame(connection2, s2Implementor.connection());
});
// Assert that the Connection used by s1 has hot changed.
assertSame(connection1, s1Implementor.connection());
// Execute a bulk operation on s1 (using connection1)
assertEquals(1, s1.createQuery("update Being set identity = 'John Doe' where identity = 'Jane Doe'").executeUpdate());
// Assert that the Connection used by s1 has hot changed.
assertSame(connection1, s1Implementor.connection());
});
// Clean up
doInHibernate(this::sessionFactory, s -> {
Human human = (Human) s.createQuery("from Being").uniqueResult();
assertEquals("John Doe", human.getIdentity());
s.createQuery("delete from Being").executeUpdate();
s.createQuery("delete from Hive").executeUpdate();
s.createQuery("delete from Location").executeUpdate();
});
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project hibernate-orm by hibernate.
the class TransactionJoiningTest method testImplicitJoining.
@Test
public void testImplicitJoining() throws Exception {
// here the transaction is started before the EM is opened...
assertFalse(JtaStatusHelper.isActive(TestingJtaPlatformImpl.INSTANCE.getTransactionManager()));
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().begin();
EntityManager entityManager = entityManagerFactory().createEntityManager();
SharedSessionContractImplementor session = entityManager.unwrap(SharedSessionContractImplementor.class);
ExtraAssertions.assertTyping(JtaTransactionCoordinatorImpl.class, session.getTransactionCoordinator());
JtaTransactionCoordinatorImpl transactionCoordinator = (JtaTransactionCoordinatorImpl) session.getTransactionCoordinator();
assertTrue(transactionCoordinator.isSynchronizationRegistered());
assertTrue(transactionCoordinator.isActive());
assertTrue(transactionCoordinator.isJoined());
assertTrue(entityManager.isOpen());
assertTrue(session.isOpen());
entityManager.close();
assertFalse(entityManager.isOpen());
assertFalse(session.isOpen());
TestingJtaPlatformImpl.INSTANCE.getTransactionManager().commit();
assertFalse(entityManager.isOpen());
assertFalse(session.isOpen());
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project jbosstools-hibernate by jbosstools.
the class ClassMetadataFacadeTest method testGetIdentifier.
@Test
public void testGetIdentifier() {
assertNull(((TestEntityPersister) classMetadataTarget).session);
final SharedSessionContractImplementor sessionTarget = createSession();
ISession sessionFacade = FACADE_FACTORY.createSession(sessionTarget);
@SuppressWarnings("serial") Serializable theObject = new Serializable() {
};
Object anotherObject = classMetadataFacade.getIdentifier(theObject, sessionFacade);
assertSame(theObject, anotherObject);
assertSame(sessionTarget, ((TestEntityPersister) classMetadataTarget).session);
}
use of org.hibernate.engine.spi.SharedSessionContractImplementor in project jbosstools-hibernate by jbosstools.
the class ClassMetadataFacadeTest method testGetIdentifier.
@Test
public void testGetIdentifier() {
assertNull(((TestEntityPersister) classMetadataTarget).session);
final SharedSessionContractImplementor sessionTarget = createSession();
ISession sessionFacade = FACADE_FACTORY.createSession(sessionTarget);
Object theObject = new Object();
Object anotherObject = classMetadataFacade.getIdentifier(theObject, sessionFacade);
assertSame(theObject, anotherObject);
assertSame(sessionTarget, ((TestEntityPersister) classMetadataTarget).session);
}
Aggregations