Vaadin 和 JPARepository:事务错误
Vaadin and JPARepository: transaction errors
我在集成 Vaadin 和 spring-data(尤其是 JPARepositories)时遇到了麻烦。
在遵循 Vaadin 团队上次网络研讨会的指导后,我设法使用 Spring 启动器(spring 引导程序)配置了我的应用程序,添加了 Vaadin、JPA 和 Postgresql 数据库。使用此方法非常简单,只需使用此
即可将实体加载到 table
@Autowired private ProjectDAO projects;
// other code here ...
grid.setContainerDataSource(new BeanItemContainer<Project>(Project.class, projects.findAll()));
我的存储库只是
@Repository
public class ProjectDAO implements JPARepository<Project, Long> {
}
而且,正如我所说,这完美无缺。问题是当我试图保存一些东西时:当尝试通过单击按钮保存项目时,例如
btnSave.addClickListener(e -> saveCurrent());
private void saveCurrent() {
// ... here I do some filesystem operations, nothing that requires DB connection
setModified();
}
public void setModified() {
project.setLastAccess(new Date());
projects.saveAndFlush(project);
}
我遇到异常:
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress.
我尝试了很多不同的东西,比如将setModified
方法标记为@Transactional
,或者将setModified
封装到服务class中,但一切总是抛出这个异常。
我觉得这行不通很奇怪 "out of the box",我不想自己处理交易,因为已经有工具可以做到这一点。
任何帮助将不胜感激
编辑 2015 年 5 月 12 日
这个问题似乎只有在使用外部服务器时才会出现,而不是spring-boot提供的嵌入式服务器。出于测试目的,我可以设法使用内置的,但最终我将不得不在现有服务器上部署应用程序,那么问题是什么? Tomcat的配置?
如果有人需要答案,我会把经过几天的思考后发现的内容留在这里。
在部署应用程序之前,我更改了由 Spring Initializr(应用程序一)生成的主要 class 上的一些配置并使其扩展 SpringBootServletInitializer
因为我正在关注我在 the official spring blog 中找到的指南。事实证明这实际上是没有必要的,因为我从一开始就在 Spring Initializr 中设置了 "WAR",因此应用程序已经有一个 class 扩展那个,因此在部署时在 Tomcat 上,Web 应用程序启动了两次,因此应用程序被配置了两次,并且实例化了两个持久性单元。这可能是错误,因为在还原我对应用程序所做的更改后一切正常。
TL;DR:如果您使用 Spring Initializr 创建 WAR 应用程序,请不要碰任何东西。
我在集成 Vaadin 和 spring-data(尤其是 JPARepositories)时遇到了麻烦。
在遵循 Vaadin 团队上次网络研讨会的指导后,我设法使用 Spring 启动器(spring 引导程序)配置了我的应用程序,添加了 Vaadin、JPA 和 Postgresql 数据库。使用此方法非常简单,只需使用此
即可将实体加载到 table@Autowired private ProjectDAO projects;
// other code here ...
grid.setContainerDataSource(new BeanItemContainer<Project>(Project.class, projects.findAll()));
我的存储库只是
@Repository
public class ProjectDAO implements JPARepository<Project, Long> {
}
而且,正如我所说,这完美无缺。问题是当我试图保存一些东西时:当尝试通过单击按钮保存项目时,例如
btnSave.addClickListener(e -> saveCurrent());
private void saveCurrent() {
// ... here I do some filesystem operations, nothing that requires DB connection
setModified();
}
public void setModified() {
project.setLastAccess(new Date());
projects.saveAndFlush(project);
}
我遇到异常:
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress.
我尝试了很多不同的东西,比如将setModified
方法标记为@Transactional
,或者将setModified
封装到服务class中,但一切总是抛出这个异常。
我觉得这行不通很奇怪 "out of the box",我不想自己处理交易,因为已经有工具可以做到这一点。
任何帮助将不胜感激
编辑 2015 年 5 月 12 日
这个问题似乎只有在使用外部服务器时才会出现,而不是spring-boot提供的嵌入式服务器。出于测试目的,我可以设法使用内置的,但最终我将不得不在现有服务器上部署应用程序,那么问题是什么? Tomcat的配置?
如果有人需要答案,我会把经过几天的思考后发现的内容留在这里。
在部署应用程序之前,我更改了由 Spring Initializr(应用程序一)生成的主要 class 上的一些配置并使其扩展 SpringBootServletInitializer
因为我正在关注我在 the official spring blog 中找到的指南。事实证明这实际上是没有必要的,因为我从一开始就在 Spring Initializr 中设置了 "WAR",因此应用程序已经有一个 class 扩展那个,因此在部署时在 Tomcat 上,Web 应用程序启动了两次,因此应用程序被配置了两次,并且实例化了两个持久性单元。这可能是错误,因为在还原我对应用程序所做的更改后一切正常。
TL;DR:如果您使用 Spring Initializr 创建 WAR 应用程序,请不要碰任何东西。