当前位置: 首页 > 知识库问答 >
问题:

在@PostConstruct中的spring boot中使用普通EntityManager持久化JPA实体

上官鸿晖
2023-03-14

我有一个最小的Spring启动应用程序,由3个类组成:一个Entity,一个尝试在@PostConstruct中填充db的组件和一个应用程序类。没有别的。

@SpringBootApplication
public class App {
  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }
}

@Component
@Transactional
public class Initializer {
    @Autowired
    EntityManager em;

    @PostConstruct
    public void populate() {
        em.persist(new MyEntity());
    }
}

@Entity
public class MyEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    int id;
}

当我运行应用程序时,我得到一个javax.persistence.Transaction必需的异常:没有实体管理器与当前线程的实际事务可用-无法可靠地处理“持久”调用

我不是唯一一个遇到这种错误的人,我读了很多帖子,但没有找到神奇的解决方法。

如果我自动装配一个EntityMananagerFactory并改为:

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(new MyEntity());
em.getTransaction().commit();
em.close();

它起作用了。问题是:有没有一种更简单的方法(在正确的位置放置正确的注释)来获取可以持久化实体的EntityManager?我有很好的理由不创建存储库(我尝试过这样做,但效果很好)。

向Jens致意

共有2个答案

干弘深
2023-03-14

据我所知,当我们想要初始化bean和配置时,会在应用程序启动时调用@PostConstruct。我认为@PostConstruct不是这样做的合适地方。

但是,您可以在entityManger上使用@PersistenceContext,而不是自动连接它。

谢俊力
2023-03-14

所以在尝试了很多不同的东西之后,我想我找到了一个可行的解决方案,其中初始化是在Application ationReadyEvent处理程序中完成的,而不是在@PostConstruct方法中完成的:

@Component
public class Initializer {

    @PersistenceContext
    EntityManager em;

    @EventListener(ApplicationReadyEvent.class)
    @Transactional
    public void init() {
        em.persist(new MyEntity());
    }
}

工作示例:https://github.com/djarnis73/spring-boot-db-init-with-jpa-entity-manager

 类似资料:
  • 摘自Java Persistence with Hibernate(Manning,2007)第419页: 我应该在会话上使用持久化()吗?Hibernate会话接口还具有一个持久化()方法。它与JPA的持久化()操作具有相同的语义学。但是,这两种操作在刷新方面有一个重要的区别。在同步期间,Hibernate会话不会将持久化()操作级联到关联的实体和集合,即使您使用此选项映射了关联。它只级联到调用

  • 问题内容: 构造bean之后,我想使用EntityManager从数据库中检索数据。在构造函数中是不可能的,因为EntityManager是在调用构造函数之后注入的。所以我试图用@PostConstruct注释的方法来做。根据API,在完成所有注入后将调用PostConstruct方法。执行查询是可行的,但是它总是返回一个空列表。如果我在其他方法中使用相同的查询,它将返回正确的结果。有人知道,为什

  • 我从我的Spring项目中删除了Spring Roo,这是不必要的,而且在eclipse STS中构建花了很多时间。我执行了一个推入,我的实体对象现在包含了旧的Roo文件的源代码。 几乎没有什么变化,包括PersistentContext管理,这看起来很奇怪。事实上,我注意到,每次创建查询时,我都需要实例化实体类以获得EntityManager? 在我的实体类中,我有

  • 最后的修正:由于Vlad的回答,我能够更新代码以使用以下内容(只需确保您还定义了bean):

  • 我遇到了一个问题,在我的JPA表中没有任何内容被持久化。据我所知,我想我理解了的基本思想。我猜出现问题的原因是,我在一个可嵌入的对象中有一个。 一个简单的例子: 有什么线索表明可能出了什么问题吗? 为了简洁起见,我将尽量使附加信息尽可能简短。 创建计算原因 创建计算历史记录 调试信息在计算历史#创建 HibernateDAO仓库 Hibernate生成的SQL 看起来HiberNate甚至没有生成