use of org.hibernate.Interceptor in project spring-framework by spring-projects.
the class HibernateTransactionManager method doBegin.
@Override
@SuppressWarnings("deprecation")
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
throw new IllegalTransactionStateException("Pre-bound JDBC Connection found! HibernateTransactionManager does not support " + "running within DataSourceTransactionManager if told to manage the DataSource itself. " + "It is recommended to use a single HibernateTransactionManager for all transactions " + "on a single DataSource, no matter whether Hibernate or JDBC access.");
}
Session session = null;
try {
if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Interceptor entityInterceptor = getEntityInterceptor();
Session newSession = (entityInterceptor != null ? getSessionFactory().withOptions().interceptor(entityInterceptor).openSession() : getSessionFactory().openSession());
if (logger.isDebugEnabled()) {
logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
}
txObject.setSession(newSession);
}
session = txObject.getSessionHolder().getSession();
if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
// We're allowed to change the transaction settings of the JDBC Connection.
if (logger.isDebugEnabled()) {
logger.debug("Preparing JDBC Connection of Hibernate Session [" + session + "]");
}
Connection con = ((SessionImplementor) session).connection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
if (this.allowResultAccessAfterCompletion && !txObject.isNewSession()) {
int currentHoldability = con.getHoldability();
if (currentHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
txObject.setPreviousHoldability(currentHoldability);
con.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
}
} else {
// Not allowed to change the transaction settings of the JDBC Connection.
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
// We should set a specific isolation level but are not allowed to...
throw new InvalidIsolationLevelException("HibernateTransactionManager is not allowed to support custom isolation levels: " + "make sure that its 'prepareConnection' flag is on (the default) and that the " + "Hibernate connection release mode is set to 'on_close' (the default for JDBC).");
}
if (logger.isDebugEnabled()) {
logger.debug("Not preparing JDBC Connection of Hibernate Session [" + session + "]");
}
}
if (definition.isReadOnly() && txObject.isNewSession()) {
// Just set to MANUAL in case of a new Session for this transaction.
session.setFlushMode(FlushMode.MANUAL);
}
if (!definition.isReadOnly() && !txObject.isNewSession()) {
// We need AUTO or COMMIT for a non-read-only transaction.
FlushMode flushMode = SessionFactoryUtils.getFlushMode(session);
if (FlushMode.MANUAL.equals(flushMode)) {
session.setFlushMode(FlushMode.AUTO);
txObject.getSessionHolder().setPreviousFlushMode(flushMode);
}
}
Transaction hibTx;
// Register transaction timeout.
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
// Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+
// Applies to all statements, also to inserts, updates and deletes!
hibTx = session.getTransaction();
hibTx.setTimeout(timeout);
hibTx.begin();
} else {
// Open a plain Hibernate transaction without specified timeout.
hibTx = session.beginTransaction();
}
// Add the Hibernate transaction to the session holder.
txObject.getSessionHolder().setTransaction(hibTx);
// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
if (getDataSource() != null) {
Connection con = ((SessionImplementor) session).connection();
ConnectionHolder conHolder = new ConnectionHolder(con);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
conHolder.setTimeoutInSeconds(timeout);
}
if (logger.isDebugEnabled()) {
logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]");
}
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
txObject.setConnectionHolder(conHolder);
}
// Bind the session holder to the thread.
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
}
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
} catch (Throwable ex) {
if (txObject.isNewSession()) {
try {
if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE) {
session.getTransaction().rollback();
}
} catch (Throwable ex2) {
logger.debug("Could not rollback Session after failed transaction begin", ex);
} finally {
SessionFactoryUtils.closeSession(session);
txObject.setSessionHolder(null);
}
}
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
}
}
use of org.hibernate.Interceptor in project hibernate-orm by hibernate.
the class InterceptorTest method testPrepareStatementFaultIntercept.
public void testPrepareStatementFaultIntercept() {
final Interceptor interceptor = new EmptyInterceptor() {
@Override
public String onPrepareStatement(String sql) {
return null;
}
};
Session s = openSession(interceptor);
try {
Transaction t = s.beginTransaction();
User u = new User("Kinga", "Mroz");
s.persist(u);
t.commit();
} catch (TransactionException e) {
assertTrue(e.getCause() instanceof AssertionFailure);
} finally {
s.close();
}
}
use of org.hibernate.Interceptor in project hibernate-orm by hibernate.
the class BatchedManyToManyTest method testLoadingNonInverseSide.
@Test
public void testLoadingNonInverseSide() {
prepareTestData();
sessionFactory().getStatistics().clear();
CollectionStatistics userGroupStats = sessionFactory().getStatistics().getCollectionStatistics(User.class.getName() + ".groups");
CollectionStatistics groupUserStats = sessionFactory().getStatistics().getCollectionStatistics(Group.class.getName() + ".users");
Interceptor testingInterceptor = new EmptyInterceptor() {
@Override
public String onPrepareStatement(String sql) {
// ugh, this is the best way I could come up with to assert this.
// unfortunately, this is highly dependent on the dialect and its
// outer join fragment. But at least this wil fail on the majority
// of dialects...
Assert.assertFalse("batch load of many-to-many should use inner join", sql.toLowerCase(Locale.ROOT).contains("left outer join"));
return super.onPrepareStatement(sql);
}
};
Session s = openSession(testingInterceptor);
s.beginTransaction();
List users = s.createQuery("from User u").list();
User user = (User) users.get(0);
assertTrue(Hibernate.isInitialized(user));
assertTrue(Hibernate.isInitialized(user.getGroups()));
user = (User) users.get(1);
assertTrue(Hibernate.isInitialized(user));
assertTrue(Hibernate.isInitialized(user.getGroups()));
// should have been just one fetch (the batch fetch)
assertEquals(1, userGroupStats.getFetchCount());
// should have been just one fetch (the batch fetch)
assertEquals(1, groupUserStats.getFetchCount());
s.getTransaction().commit();
s.close();
}
use of org.hibernate.Interceptor in project hibernate-orm by hibernate.
the class InterceptorTest method testPrepareStatementIntercept.
@Test
@TestForIssue(jiraKey = "HHH-6594")
public void testPrepareStatementIntercept() {
final Queue<String> expectedSQLs = new LinkedList<String>();
// Transaction 1
expectedSQLs.add("insert");
// Transaction 2
expectedSQLs.add("select");
expectedSQLs.add("select");
// Transaction 3
expectedSQLs.add("select");
expectedSQLs.add("select");
expectedSQLs.add("update");
// Transaction 4
expectedSQLs.add("select");
expectedSQLs.add("delete");
final Interceptor interceptor = new EmptyInterceptor() {
@Override
public String onPrepareStatement(String sql) {
assertNotNull(sql);
String expectedSql = expectedSQLs.poll().toLowerCase(Locale.ROOT);
assertTrue("sql:\n " + sql.toLowerCase(Locale.ROOT) + "\n doesn't start with \n" + expectedSql + "\n", sql.toLowerCase(Locale.ROOT).startsWith(expectedSql));
return sql;
}
};
Session s = openSession(interceptor);
Transaction t = s.beginTransaction();
User u = new User("Lukasz", "Antoniak");
s.persist(u);
t.commit();
s.close();
s = openSession(interceptor);
t = s.beginTransaction();
s.get(User.class, "Lukasz");
s.createQuery("from User u").list();
t.commit();
s.close();
u.setPassword("Kinga");
s = openSession(interceptor);
t = s.beginTransaction();
s.merge(u);
t.commit();
s.close();
s = openSession(interceptor);
t = s.beginTransaction();
s.delete(u);
t.commit();
s.close();
assertTrue(expectedSQLs.isEmpty());
}
Aggregations