【问题标题】:Vaadin and JPARepository: transaction errorsVaadin 和 JPARepository:事务错误
【发布时间】:2015-07-21 23:57:29
【问题描述】:

我在集成 Vaadin 和 spring-data(尤其是 JPARepositories)时遇到了麻烦。

在 Vaadin 团队的上次网络研讨会指导下,我设法使用 Spring starter (spring boot) 配置了我的应用程序,添加了 Vaadin、JPA 和 Postgresql 数据库。使用此方法非常简单,只需使用此方法即可将实体加载到表中即可使用

@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 封装到一个服务类中,但一切总是抛出这个异常。

我觉得这很奇怪,这不能“开箱即用”,我宁愿自己不处理交易,因为已经有工具可以做到这一点。

任何帮助将不胜感激

编辑 12/05/2015

这个问题好像只有在使用外部服务器时才会出现,而不是spring-boot提供的嵌入式服务器。出于测试目的,我可以设法使用内置的,但最终我将不得不在现有服务器上部署应用程序,那么问题可能是什么? Tomcat的配置?

【问题讨论】:

  • Spring @Transactional 仅在标有它的方法位于从 SpringContext 创建的 bean 中时才有效...否则有一种称为 Open Session In View 的技术,它不是最好的可扩展解决方案,但是它可以工作并且非常易于使用。
  • 这解释了为什么 @Transactional 在 Vaadin 的 @SpringView 视图中不起作用,但是我也在 @Service 类中放置了相同的注释并且仍然抛出异常。一旦我使用@Autowired,不应该从SpringContext创建@Service吗?
  • 是的,您还需要在您的应用程序中启用事务,检查reference,但是如果您使用的是 spring xml 配置,则有两种方法带有标记,或者如果使用注释,则您正在使用基于注释的配置
  • 是的,我之前看过那个文档,我在@Configuration 注释类中使用了@EnableTransactionManagement,它给出了Web 应用程序的配置,这让我很困扰,似乎没有什么可以解决的这个

标签: java spring-boot vaadin spring-data-jpa vaadin7


【解决方案1】:

如果有人需要答案,我会在这里留下几天后我发现的答案。

在部署应用程序之前,我更改了由 Spring Initializr(应用程序之一)生成的主类的一些配置,并使其扩展 SpringBootServletInitializer,因为我遵循了在 the official spring blog 中找到的指南。事实证明这实际上是没有必要的,因为我从一开始就在 Spring Initializr 中设置了“WAR”,因此应用程序已经有一个扩展该类的类,因此在 Tomcat 上部署它时,Web 应用程序启动了两次,所以应用程序被配置了两次,并且实例化了两个持久性单元。这可能是错误,因为在恢复我对应用程序所做的更改后一切正常。

TL;DR:如果您使用 Spring Initializr 创建 WAR 应用程序,请不要碰任何东西。

【讨论】:

    猜你喜欢
    • 2021-07-24
    • 1970-01-01
    • 2019-05-08
    • 2017-08-25
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    相关资源
    最近更新 更多