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 应用程序,请不要碰任何东西。