2014-11-12 4 views
3

Я пытаюсь работать с Hibernate и Spring DataSourceTransactionManager для обработки функций фиксации и откат, но, вероятно, я ничего не получу.Hibernate и Spring DataSourceTransactionManager

Перед использованием Spring DataSourceTransactionManager, это был один из моего класса DAO

package com.springgestioneerrori.DAO; 

    public class UtenteDAO extends DAOBase{ 

     public void salvaUtente(Utente utenteIn) throws DAOException{ 

      Session session = getHibernateSession(); //from this method I get Hibernate SessionFactory 
       try{ 
        session.beginTransaction();    
        session.saveOrUpdate(Object); 
        session.getTransaction().commit();  
        } 
       catch(Exception e){ 
        session.getTransaction().rollback() 
       } 
     } 
} 

Это класс, который дает мне SessionFactory

private static final SessionFactory sessionFactory = buildSessionFactory(); 

      private static SessionFactory buildSessionFactory() { 
       try { 
        // Create the SessionFactory from hibernate.cfg.xml 
        return new AnnotationConfiguration().configure().buildSessionFactory(); 
       } 
       catch (Throwable ex) { 
           System.err.println("Initial SessionFactory creation failed." + ex); 
        throw new ExceptionInInitializerError(ex); 
       } 
      } 

      public static SessionFactory getSessionFactory() { 
       return sessionFactory; 
      } 

      public static void shutdown() {    
       getSessionFactory().close(); 
      } 

public Session getHibernateSession(){ 
    Session session = HibernateUtil.getSessionFactory().openSession(); 
    return session; 
} 

Теперь я пытаюсь использовать DataSourceTransactionManager в декларативной путь. После некоторых примеров в Интернете, я писал:

<tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />   

<tx:advice id="txAdvice" transaction-manager="transactionManager"> 
    <tx:attributes> 
     <tx:method name="salvaUtente"/> 
    </tx:attributes> 
</tx:advice> 

<aop:config> 
    <aop:pointcut id="userDaoTxPointcut" expression="execution(* com.springgestioneerrori.DAO.UtenteDAO.salvaUtente(..))" /> 
    <aop:advisor advice-ref="txAdvice" pointcut-ref="userDaoTxPointcut" /> 
</aop:config>  

Теперь, что я должен написать внутри метода salvaUtente() для выполнения множества вставок, например, как эти

session.saveOrUpdate(User); 
    session.saveOrUpdate(UserCredentials); 
    session.saveOrUpdate(UserOtherDetails); 

и изготовление рукоятки пружины и откат?

+0

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

+0

Все вставки связаны друг с другом, если одна вставка не работает, другие вставки не должны иметь никакого эффекта. – MDP

ответ

4

Сначала вы используете неправильный менеджер транзакций. DataSourceTransactionManager не для Hibernate, а для простого JDBC. Если вы используете простой Hibernate, используйте HibernateTransactionManager. (Предположим, что вы используете Hibernate 4 здесь!).

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

Теперь я также хотел бы предложить использовать @Transactional вместо блока <tx:advice /> и <aop:config />. Делает вашу конфигурацию проще. Просто удалите 2 упомянутых блока и замените их на <tx:annotation-driven />.

<tx:annotation-driven /> 

Теперь ваш код является неправильным, поскольку вы начинаете транзакции самостоятельно. Аннотируйте свой метод с помощью @Transactional (после добавления выше) и удалите код обработки транзакций.

@Transactional 
public void salvaUtente(Utente utenteIn) throws DAOException{ 
    Session session = getHibernateSession(); //from this method I get Hibernate SessionFactory 
    session.saveOrUpdate(Object); 
} 

Теперь я не знаю, что ваш метод getHibenateSession делает, но убедитесь, что вы не используете openSession на SessionFactory получить сеанс. Вместо этого используйте getCurrentSession.

protected Session getHibernateSession() { 
    return sessionFactory.getCurrentSession(); 
} 

Ваш текущий BaseDAO класс является некорректной. Удалите buildSessionFactory и удалите static final. Пусть Spring настроит и введет SessionFactory.

public abstract class BaseDAO { 

    @Autowired 
    private SessionFactory sessionFactory; 

    protected Session getHibernateSession() { 
     return sessionFactory.getCurrentSession(); 
    } 
} 

В вашей конфигурации добавьте конфигурацию для LocalSessionFactoryBean.

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    ... Other Hibernate Properties 
</bean> 

Это в основном все, что нужно. Это также подробно объясняется в the Spring Reference guide. Я настоятельно рекомендую прочитать.

+0

Я отредактировал мое сообщение и добавил класс, который дал мне sessionFactory – MDP

+0

Если io попытается использовать getCurrentSession вместо openSessione, то настройте No CurrentSessionContext! – MDP

+0

Тогда ваша конфигурация неверна (см. Мой измененный ответ) и, пожалуйста, прочитайте ссылку, которая теперь включена в нее. В справочном руководстве подробно описывается, как настроить работу в спящем режиме. Я настоятельно рекомендую прочитать. –

0

Я хотел бы предложить

@Transaction(rollbackFor = {if you need to rollback on certain checked exception}) 
salvaUtente() 

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

если есть исключение в любой момент salvaUtente в сделке будет рулет поддержке иначе сделка будет совершена после того, как метод существовало

+0

Я все еще пропускаю шаг. Что мне следует написать insde salveUtente() для управления 3-вставкой session.saveOrUpdate (User); Session.saveOrUpdate (UserCredentials); session.saveOrUpdate (UserOtherDetails); – MDP