2014-09-30 5 views
4

Я использую весну и спящий режим в своем приложении и используя весеннюю транзакцию.hibernate session.flush с spring @transactional

Итак, у меня есть сервисный уровень с аннотацией @transaction по методам и DAO-слою, имеющим методы для запроса к базе данных.

@Transactional(readOnly = false) 
public void get(){ 

} 

Вопрос в том, когда я хочу, чтобы сохранить объект в базе данных, то я должен использовать session.flush() в конце DAO слоя method.Why?

Я думаю, что если у меня есть аннотированная транзакция @, тогда весна должна автоматически совершать транзакцию по завершении метода обслуживания.

DAO слой:

public BaseEntity saveEntity(BaseEntity entity) throws Exception { 
     try { 
      Session session = sessionFactory.getCurrentSession(); 
      session.saveOrUpdate(entity); 
      session.flush(); 
     } catch (HibernateException he) { 
      throw new Exception("Failed to save entity " + entity); 
     } 
     return entity; 
    } 

Сервис слой:

@Transactional(readOnly = false) 
    public BaseEntity saveEntity(BaseEntity entity) throws Exception { 
     return dao.saveEntity(entity); 
    } 

весна конфигурации:

<context:property-placeholder properties-ref="deployProperties" /> 

    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <!-- Activate Spring Data JPA repository support --> 
    <jpa:repositories base-package="com" /> 

    <!-- Declare a datasource that has pooling capabilities--> 
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
     destroy-method="close" 
     p:driverClass="${app.jdbc.driverClassName}" 
     p:jdbcUrl="${app.jdbc.url}" 
     p:user="${app.jdbc.username}" 
     p:password="${app.jdbc.password}" 
     p:acquireIncrement="5" 
     p:idleConnectionTestPeriod="60" 
     p:maxPoolSize="100" 
     p:maxStatements="50" 
     p:minPoolSize="10" /> 

    <!-- Declare a JPA entityManagerFactory --> 
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
     p:persistenceXmlLocation="classpath*:META-INF/persistence.xml" 
     p:persistenceUnitName="hibernatePersistenceUnit" 
     p:dataSource-ref="dataSource" 
     p:jpaVendorAdapter-ref="hibernateVendor"/> 

    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" 
     p:dataSource-ref="dataSource" p:configLocation="${hibernate.config}" 
     p:packagesToScan="com" /> 

    <!-- Specify our ORM vendor --> 
    <bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" 
       p:showSql="false"/> 

    <!-- Declare a transaction manager--> 
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
     p:entityManagerFactory-ref="entityManagerFactory"/> 
+1

Весна делает это за вас, и 'readonly = false' является значением по умолчанию, вы его не объявляете – Jaiwo99

+0

Я думаю, что автоматическая фиксация не предназначена для немедленного сброса' Session' в DB, но внесение изменений в эту транзакцию доступно для других транзакций, работающих с той же «сессией». –

+1

Если вы правильно настроили транзакции, тогда да ... Но ваша установка испорчена. Почему вы используете «SessionFactory» и «EntitymanagerFactory»? Вы используете только один менеджер транзакций. Основная проблема - ваша настройка. –

ответ

0

Да, если у вас есть @Transactional для метода DAO, то вам не нужно промыть сеанс вручную, hibernate позаботится о том, чтобы очистить сеанс как часть если операции в методе успешны.

Проверить эту ссылку, чтобы узнать о том, как работает @Transactional - Spring - @Transactional - What happens in background?

+0

Спасибо, но без session.flush, обновления не отражаются в базах данных, я что-то пропустил? –

+1

Я вас не понял, вы можете уточнить, что вы имеете в виду? – Chaitanya

+0

Если я не пишу session.flush в dao-слое, тогда записи не будут сохраняться в базе данных, пока это должно быть, поскольку я использую @transactional в уровне обслуживания, так есть ли проблема с конфигурацией или что-то еще? –

0

По умолчанию, спящий режим складывает свои запросы, чтобы они могли быть оптимизированы, когда они, наконец, выполнены на базе данных.

Точка отверстия флеша - это очистить этот стек и выполнить его в транзакции в базе данных. Вы покидаете «сохранить» дом jvm и выполняете свой запрос в большой странной базе данных.

Вот почему вы не можете выбрать то, что вы только что сохранили без флеша. Его просто нет в базе данных.

Значение commit завершается после транзакции и делает изменения базы данных видимыми для других. Как только фиксация выполнена, возврат невозможен.

Откровенно говоря, я не совсем уверен, что это лучшая практика, но для обычных операций CRUD вы можете добавить флеш в свой слой dao. Таким образом, вам не нужно беспокоиться об этом в сервисном слое.

Если вы хотите, чтобы java оптимизировал вашу транзакцию, вам придется добавить ее в свой сервисный уровень. Но помните, что вам не нужно решать проблемы производительности, когда их нет! Сбрасывание всего кода в сервисный уровень не подходит для чтения кода. Держите его простым и глупым;)

Смежные вопросы