Сканирование компонентов
Перво-наперво: вы используете @Controller, @Service, @Repository и @Autowired, но ничего с ними не делаете.Я рекомендую использовать сканирование пути к классам .Удалите bean-компоненты «testServiceDAO» и «testService» из вашего весеннего контекстного файла и вместо этого используйте:
<context:component-scan base-package="com.test.spring.ws"/>
, который найдет и создаст эти bean-компоненты по их аннотациям вместо того, чтобы требовать их объявления в XML.Добавьте @Autowired в поле testServiceDAO
вашего сервиса и в поле sessionFactory
вашего DAO.Удалите сеттеры для этих полей.Они больше не нужны.Тэг компонента-сканирования также сделает автоматическую разводку для вас.Чтобы использовать пространство имен context
, вам необходимо добавить его в корневой элемент.Например:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
Управление транзакциями
Для используйте @ Transactional , как сказал Шон, вам нужно добавить элемент к вашей пружинефайл контекста:
<tx:annotation-driven/>
Поскольку ваш bean-компонент менеджера транзакций называется "actionManager ", он найдет его автоматически.Вам также нужно добавить пространство имен "tx" в ваш корневой элемент, чтобы оно выглядело примерно так:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
Чтобы это работало, вам нужно удалить и session.beginTransaction()
, и session.close()
от вашего метода DAO.Открытие вашей собственной транзакции таким образом смешивает программную и декларативную разграничение транзакций, и декларативный способ обычно лучше.Кроме того, вы никогда не должны когда-либо закрывать сеанс в DAO в реальном проекте.Это доставит вас ко всем видам неприятностей.
Обработка исключений
Ваш MySQLIntegrityConstraintViolationException
, будучи исключением для конкретной базы данных, будет пойман Hibernate и упакован в ConstraintViolationException , который будет исходить из вашего DAO;однако, поскольку ваш DAO теперь является @Repository, вы можете воспользоваться переводом исключений Spring .При этом исключение Hibernate будет перехвачено Spring и переведено в DataIntegrityViolationException .Обработка исключений в базе данных всегда забавна!
Управление сеансами
Используете ли вы OpenSessionInViewFilter или OpenSessionInViewInterceptor ?Если это так, сеанс Hibernate открывается при первом получении запроса и закрывается после записи ответа.Если нет, то сеанс не начинается до тех пор, пока не начинается транзакция (с помощью метода @Transactional), и закрывается, когда эта транзакция завершается.С фильтром / перехватчиком вы можете делать вещи на уровне «представления», которые требуют обратного вызова к базе данных - особенно когда у вас есть ленивые отношения или лениво загруженные объекты, которые вам нужны для визуализации представления.Если сеанс недоступен - как и если он существует только для длины метода транзакционного сервиса - вы не можете делать эти вещи в представлении и получите печально известную LazyInitializationException .
Что касается ошибки «не очищать сессию после возникновения исключения», которую я получаю, я не вижу сразу ничего, что заставило бы меня думать, что это должно произойти.Возможно, что-то в контексте пружины вашего веб-уровня неправильно настроено, или, может быть, есть какое-то странное взаимодействие в том, как вы обрабатываете транзакцию и сеанс непосредственно в DAO.