001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.orm.jpa.vendor;
018:
019: import java.sql.Connection;
020: import java.sql.SQLException;
021:
022: import javax.persistence.EntityManager;
023: import javax.persistence.PersistenceException;
024:
025: import org.hibernate.FlushMode;
026: import org.hibernate.Session;
027: import org.hibernate.ejb.HibernateEntityManager;
028:
029: import org.springframework.jdbc.datasource.ConnectionHandle;
030: import org.springframework.jdbc.datasource.SimpleConnectionHandle;
031: import org.springframework.orm.jpa.DefaultJpaDialect;
032: import org.springframework.transaction.TransactionDefinition;
033: import org.springframework.transaction.TransactionException;
034:
035: /**
036: * {@link org.springframework.orm.jpa.JpaDialect} implementation for
037: * Hibernate EntityManager. Developed and tested against Hibernate 3.2.
038: *
039: * @author Costin Leau
040: * @author Juergen Hoeller
041: * @since 2.0
042: */
043: public class HibernateJpaDialect extends DefaultJpaDialect {
044:
045: public Object beginTransaction(EntityManager entityManager,
046: TransactionDefinition definition)
047: throws PersistenceException, SQLException,
048: TransactionException {
049:
050: super .beginTransaction(entityManager, definition);
051: Session session = getSession(entityManager);
052: FlushMode flushMode = session.getFlushMode();
053: FlushMode previousFlushMode = null;
054: if (definition.isReadOnly()) {
055: // We should suppress flushing for a read-only transaction.
056: session.setFlushMode(FlushMode.MANUAL);
057: previousFlushMode = flushMode;
058: } else {
059: // We need AUTO or COMMIT for a non-read-only transaction.
060: if (flushMode.lessThan(FlushMode.COMMIT)) {
061: session.setFlushMode(FlushMode.AUTO);
062: previousFlushMode = flushMode;
063: }
064: }
065: return new SessionTransactionData(session, previousFlushMode);
066: }
067:
068: public void cleanupTransaction(Object transactionData) {
069: ((SessionTransactionData) transactionData).resetFlushMode();
070: }
071:
072: @Override
073: public ConnectionHandle getJdbcConnection(
074: EntityManager entityManager, boolean readOnly)
075: throws PersistenceException, SQLException {
076:
077: Session session = getSession(entityManager);
078: Connection con = session.connection();
079: return (con != null ? new SimpleConnectionHandle(con) : null);
080: }
081:
082: protected Session getSession(EntityManager em) {
083: return ((HibernateEntityManager) em).getSession();
084: }
085:
086: private static class SessionTransactionData {
087:
088: private final Session session;
089:
090: private final FlushMode previousFlushMode;
091:
092: public SessionTransactionData(Session session,
093: FlushMode previousFlushMode) {
094: this .session = session;
095: this .previousFlushMode = previousFlushMode;
096: }
097:
098: public void resetFlushMode() {
099: if (this.previousFlushMode != null) {
100: this.session.setFlushMode(this.previousFlushMode);
101: }
102: }
103: }
104:
105: }
|