java - 正确使用 Spring mvc 3 和 hibernate (Spring ORM)

标签 java hibernate spring spring-mvc

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

  1. Spring context
  2. Controller
  3. Service Interface
  4. Service Implementation
  5. DAO interface
  6. DAO implementation

我想尽可能多地使用 spring MVC,如何让 session 打开/关闭由@Transactional 处理?

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

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry

我怎样才能捕获这个?

对于我发出的每个下一个请求,我都会得到这个异常:

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

我做错了什么?谁能对我的项目提出一些改进建议?

最佳答案

组件扫描

首先要做的是:您正在使用@Controller、@Service、@Repository 和@Autowired,但您不对它们做任何事情。我建议使用 classpath scanning .从您的 spring 上下文文件中删除“testServiceDAO”和“testService”bean,而是使用:

<context:component-scan base-package="com.test.spring.ws"/>

这将通过注解找到并创建这些 bean,而不是要求您在 XML 中声明它们。将 @Autowired 添加到服务中的 testServiceDAO 字段和 DAO 中的 sessionFactory 字段。删除这些字段的 setter 。他们不再需要了。 component-scan 标签也会为你做 Autowiring 。要使用 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">

事务管理

收件人use @Transactional ,正如 Sean 所说,您需要将一个元素添加到您的 spring 上下文文件中:

<tx:annotation-driven/>

由于您的事务管理器 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">

要使其有任何工作机会,您需要从 DAO 方法中删除 session.beginTransaction()session.close()。以这种方式打开您自己的事务混合了编程式和声明式事务划分,并且声明式方式通常更好。此外,您永远不要在真实项目中关闭 DAO 中的 session 。那会让你陷入各种麻烦。

异常处理

您的 MySQLIntegrityConstraintViolationException 作为特定于数据库的异常,将被 Hibernate 捕获并包装在 ConstraintViolationException 中,这就是您的 DAO 的结果;但是,由于您的 DAO 现在是一个 @Repository,您可以从 Spring 的 exception translation 中获益。 .这样,Hibernate 异常将被 Spring 捕获并转换为 DataIntegrityViolationException。 .数据库异常处理总是很有趣!

session 管理

您使用的是 OpenSessionInViewFilter 吗?或 OpenSessionInViewInterceptor ?如果是这样,Hibernate session 将在首次收到请求时打开,并在写入响应后关闭。如果不是,则 session 不会开始,直到事务开始(在 @Transactional 方法中),并在该事务完成时关闭。使用过滤器/拦截器,您可以在“ View ”层中执行需要回调数据库的操作——特别是当您具有呈现 View 所需的延迟关系或延迟加载对象时。如果 session 不可用——如果它只在事务服务方法的长度内存在——你就不能在 View 中做那些事情,你会得到臭名昭著的LazyInitializationException。 .

至于您收到的“异常发生后不刷新 session ”错误,我没有立即看到任何让我认为应该发生的事情。也许您的 web 层 spring 上下文中的某些内容配置错误,或者您直接在 DAO 中处理事务和 session 的方式可能存在一些奇怪的相互作用。

关于java - 正确使用 Spring mvc 3 和 hibernate (Spring ORM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6709750/

相关文章:

java - 无法在 Person 和 Address 类之间建立 'many-to-many' 关系

java - Hibernate问题-映射ArrayList

java - 通过源码包更新现有的类定义

java - 应用程序结束后,hibernate 不会将数据保存到本地 h2 数据库

mysql - 如何使用 Java 和 spring/hibernate 在我的数据库中正确插入日期(在我的数据库中得到错误的时间)?

spring - 是否可以将系统路径设置为 spring 上下文

java - Spring Security + OAuth,如果访问 token 不存在则回退

java - native 查询中未设置参数

java - Seam Solder 的 @Requires 注释应该接收字符串还是类?

java - 在 return 语句中创建一个匿名类