使用hibernate正确使用Spring mvc 3(Spring ORM)

Lon*_*don 8 java spring hibernate spring-mvc

我正在开始一个新项目,这次尝试做正确的事情(所以不止一个问题),我可能需要一些帮助,我不确定我做错了什么:

  1. 春天的背景
  2. 调节器
  3. 服务接口
  4. 服务实施
  5. DAO接口
  6. DAO实施

我想尽可能多地利用spring MVC,如何通过@Transactional处理会话打开/关闭?

如何捕获异常(即非现有记录或数据库失败)(如果有).即我的数据库不接受像这样的重复条目:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry
Run Code Online (Sandbox Code Playgroud)

我怎么能抓住这个?

对于我提出的每个下一个请求,我得到了这个例外:

org.hibernate.AssertionFailure: null id in com.test.spring.ws.service.impl.TestObject entry (don't flush the Session after an exception occurs)
Run Code Online (Sandbox Code Playgroud)

我做错了什么?有人可以建议我的项目有一些改进吗?

Rya*_*art 12

组件扫描

首先要做的事情是:你正在使用@ Controller,@ Service,@ Repository和@Autowired,但是你没有对它们做任何事情.我建议使用类路径扫描.从spring上下文文件中删除"testServiceDAO"和"testService"bean,改为使用:

<context:component-scan base-package="com.test.spring.ws"/>
Run Code Online (Sandbox Code Playgroud)

这将通过注释找到并创建这些bean,而不是要求您在XML中声明它们.将@Autowired添加到testServiceDAO服务中的sessionFactory字段和DAO中的字段.删除这些字段的setter.他们不再需要了.组件扫描标签也将为您进行自动装配.要使用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">
Run Code Online (Sandbox Code Playgroud)

交易管理

使用@Transactional,正如肖恩所说,你需要在spring上下文文件中添加一个元素:

<tx:annotation-driven/>
Run Code Online (Sandbox Code Playgroud)

由于您的事务管理器bean名为"transactionManager",因此它将自动找到它.您还需要将"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">
Run Code Online (Sandbox Code Playgroud)

对于这个工作有任何的机会,你需要同时删除session.beginTransaction()session.close()从您的DAO方法.以这种方式打开自己的事务是混合程序化和声明式事务划分,声明方式通常更好.此外,你应该永远永远关闭会话的DAO在一个真正的项目.那会让你遇到各种各样的麻烦.

异常处理

MySQLIntegrityConstraintViolationException,作为一个特定数据库的异常,会由Hibernate抓住并包裹在ConstraintViolationException,这是什么会出来你的DAO的; 但是,既然你的DAO现在是一个@Repository,你可以从Spring的异常翻译中受益.有了这个,Hibernate异常将被Spring捕获并转换为DataIntegrityViolationException.数据库异常处理总是很有趣!

会话管理

您使用的是OpenSessionInViewFilter还是OpenSessionInViewInterceptor?如果是这样,则在首次接收请求时打开Hibernate会话,并在写入响应后关闭Hibernate会话.如果没有,则会话直到事务开始(在@Transactional方法)才开始,并且在该事务完成时关闭.使用过滤器/拦截器,您可以在需要回调数据库的"视图"层中执行操作 - 特别是当您具有渲染视图所需的延迟关系或延迟加载对象时.如果会话不可用 - 因为它不是仅存在于事务服务方法的长度 - 您不能在视图中执行这些操作,并且您将获得臭名昭着的LazyInitializationException.

至于"在发生异常后不刷新会话"错误,你得到的错误,我没有立即看到任何会让我觉得应该发生的事情.您的Web层Spring环境中的某些内容可能是配置错误,或者您可能在DAO中直接处理事务和会话方面存在一些奇怪的相互作用.