2012-05-29 1 views
3

Использование Hibernate 4 и Spring 3.1. Просто вставать и бегать с ним, так что это может быть недостаток понимания с моей стороны. У меня есть метод в классе Service, который вызывает метод в классе DAO для извлечения некоторых данных с помощью Hibernate. Я комментирую метод службы с помощью @Transactional, но получаю сообщение об ошибке при вызове метода getCurrentSession в методе DAO. Если я также аннотирую метод DAO с помощью @Transactional, то данные будут успешно восстановлены. Я не понимаю, почему, хотя я бы подумал, что аннотация @Transactional в методе службы создала сессию Hibernate, связала бы ее с потоком и что этот сеанс будет возвращен в классе DAO при вызове getCurrentSession. Может ли кто-нибудь объяснить, почему это так, или если я делаю что-то неправильно, спасибо?Ошибка «Сессия найдена для текущего потока» в DAO при маркировке Класс обслуживания как Транзакция

корня context.xml:

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

Класс обслуживания:

public class BlahServiceImpl implements BlahService { 

    @Transactional 
    public Blah GetMostRecentBlah() { 
     BlahDAO blahDAO = DAOFactory.GetBlahDAO(); 
     return blahDAO.GetMostRecentBlah(); 
    } 
} 

DAO класс:

private SessionFactory sessionFactory; 

public void setSessionFactory(SessionFactory sessionFactory) { 
    this.sessionFactory = sessionFactory; 
} 

public Blah GetMostRecentBlah() { 
    return (Blah)sessionFactory.getCurrentSession().createQuery("from Blah where blahID = (select max(blahID) from Blah)").uniqueResult(); 
} 

Ошибка:

org.hibernate.HibernateException: No Session found for current thread 
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97) 
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1039) 
com.blah.blah.DAO.BlahDAOImpl.GetMostRecentBlah(BlahDAOImpl.java:18) 

Как я уже сказал, если я комментирую функцию DAO с помощью @Transactioanl (а также метод службы), это работает, но я не понимаю, почему.

+0

Не могли бы мы увидеть код, который вызывает услугу? –

+0

И как выглядит ваш DAOFactory? –

ответ

3

Возможны две возможные причины.

1) Ваш сервисный компонент находится в отдельном ApplicationContext, который не включает транзакции с аннотацией.

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

Чтобы определить, в чем проблема, или определить, есть ли какая-то другая проблема, покажите файл контекста, который заставляет ваш bean-компонент службы, и покажите код, в котором вы получаете экземпляр своей службы.

+0

или 3) Мой класс обслуживания даже не был объявлен как Bean! Говорил, что я новичок в этом. – CodeClimber

+0

Это фактически подпадает под 2): вы получали экземпляр службы, вызывая его конструктор напрямую, а не получая его из Spring. Рад, что смог помочь! –

1

раствора может быть:

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

, как классы не проксированные.

В противном случае, если у вас есть к прокси частных методов, как транзакционные (как я сталкивался), вы можете оказаться в добавлении AspectJ вместо CGLIB, а затем следующая конфигурация может помочь

<!-- switches on the load-time weaving --> 
    <context:load-time-weaver /> 

    <!-- proxies classes with aspectj and you may have @Transaction annotations for managing transactions-->  
    <tx:annotation-driven proxy-target-class="true" mode="aspectj" transaction-manager="transactionManager" /> 

после этого запуска сервера с JVM аргумент

-javaagent:/path-to/spring-instrument-{spring-version}.jar 
Смежные вопросы