【发布时间】:2015-06-02 20:39:33
【问题描述】:
我已经配置了带有注释驱动的 spring jpa。我希望以下代码在方法存在时将更改持久保存到数据库。
@Transactional
public Foo changeValue(int id){
final Foo foo = fooRepository.findOne(id);
if(foo != null){
foo.setValue("new value");
//fooRepository.save(foo);
}
}
FooRepository 是 JPARepository 并且 foo 对象正在被获取,因此它被管理。根据我读到的关于@Transactional 我希望,即使没有fooRepository.save(foo) 调用,数据库中foo 的值列中的更改也会在方法存在时保持不变。但是,只有当我取消注释对 fooRepository.save(foo) 的调用时才会发生这种情况
不抛出异常,jpa 数据源的配置如下。
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory" />
<tx:annotation-driven transaction-manager="transactionManager" />
<context:component-scan
base-package="com.example.package.data" />
<jpa:repositories
base-package="com.example.package.data.repository"
entity-manager-factory-ref="entityManagerFactory"
transaction-manager-ref="transactionManager" />
有什么想法吗?
更新
我有一个ContextLoaderListener 和一个DispatcherServlet,但我没有对两者进行组件扫描。
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
</servlet>
....
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
更新
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
我做到了
<context:component-scan base-package="com.example.package">
<context:exclude-filter type="regex"
expression="com.example.package.data.*" />
<context:exclude-filter type="regex"
expression="com.example.package.web.controller.*" />
<context:exclude-filter type="regex"
expression="com.example.package.web.service.*" />
</context:component-scan>
在servlet-context
<context:component-scan base-package="com.example.package.web" />
【问题讨论】:
-
我严重怀疑 Spring 是否会自动保存您的实体,因为您在事务中修改了附加的实体。你能给我们参考任何说明这一点的文件吗?如果您查看this Spring Documentation,尤其是该页面上的 2.16 示例,那么您可以看到代码在事务性
addRoleToAllUsers方法中显式调用了存储库save方法。 -
@DuncanKinnear Spring 在任何情况下都不会保存实体,这是 Hibernate 的工作。
-
您的非工作示例看起来完全像这样吗?或者这是一个示范性的简短例子?
-
您是否同时拥有
ContextLoaderListener和DispatcherServlet?在<context:component-scan />?如果是,您有 2 个相同 bean 的实例 1 个事务性的,另一个没有,最后一个将被使用。 -
@DraganBozanovic 是的,非工作示例看起来像这样。我只是更改了变量名并省略了根据我的调试未达到的错误处理。
标签: spring hibernate jpa transactions