【问题标题】:Persisting JPA entity using plain EntityManager in spring boot in @PostConstruct在@PostConstruct的春季启动中使用普通EntityManager持久化JPA实体
【发布时间】:2019-06-17 15:02:55
【问题描述】:

我有一个最小的 Spring Boot 应用程序,由 3 个类组成:一个实体、一个尝试在 @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.TransactionRequiredException: No EntityManager with actual transaction available for current thread - 无法可靠地处理“持久”调用

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

如果我自动装配 EntityMananagerFactory 而是这样做:

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

它有效。问题是:有没有更简单的方法(在正确的位置放置正确的注释)来获得可以持久化实体的 EntityManager?我有充分的理由不创建存储库(我尝试这样做并且有效)。

最好的问候詹斯

【问题讨论】:

  • Spring 事务管理是最简单的方法。但是,这不会使事务在 PostConstruct 方法中可用。尝试以这种方法初始化数据是完全错误的做法。您用这种方法初始化 bean,而不是数据库。
  • 这可能会有所帮助:stackoverflow.com/questions/17346679/…
  • 感谢@MaximMarkov,它帮助我解决了我的问题,很快就会发布一个可行的解决方案。
  • @Gimby 是否有在应用程序启动时初始化数据库的正确方法(可能是@EventListener)?我记得不久前研究了如何在应用程序启动时以编程方式初始化/填充数据库,但没有找到任何最佳实践。

标签: java spring-boot jpa entitymanager spring-transactions


【解决方案1】:

所以在尝试了很多不同的东西之后,我认为我找到了一个可行的解决方案,其中初始化是在 ApplicationReadyEvent 处理程序中完成的,而不是在 @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

【讨论】:

    【解决方案2】:

    根据我的理解,当我们想要初始化 bean 和配置时,@PostConstruct 会在应用启动时被调用。我认为@PostConstruct 不适合这样做。

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

    【讨论】:

    • 是的,我已经看到了关于在@PostConstruct/InitializingBean 中没有事务的几个指针。如果您使用 Repository 而不是 EntityManager,您确实拥有它们,我想这让我感到困惑。我确实尝试了@PersistenceContext,但没有发现任何行为差异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-25
    • 2014-11-27
    • 1970-01-01
    • 2021-08-31
    相关资源
    最近更新 更多