我有一个Spring / JPA / Hibernate应用程序,它在mysql表中维护状态数据。应用程序依赖于正确初始化的状态数据。也就是说,当应用程序初始化时,我想确保一个已知的表包含两行 - 每行包含两个已知的主键值。
该表是" JPA管理的" (对不起,如果该术语不正确) - 我有一个@Entity
类,它将表中的每一行映射到该类的实例,以及一个操作(持久化,检索)该实例的{DA}类@Entity
1}}。
尝试解决此问题的我(不成功)在使用initialize()
(以及@PostConstruct
)注释的DAO上使用了@Transactional(read-only = false)
方法。该方法实例化@Entity
的两个实例,并调用EntityManager
来保持它们(我使用persist而不是merge来避免覆盖现有状态并捕获预期的EntityExistsException
如果行已存在)。
我已确认正在调用initialize()
方法并在persist(...)
上调用EntityManager
方法,但未插入数据库行 - 我&#39 ; ve检查了mysql语句日志,并且没有预期的INSERT
语句。
我不能成为第一个想要在JPA管理的表中初始化数据的人,对吧?是否有一个"最佳实践"进行这种初始化?
谢谢!
PS:虽然该表是" JPA管理的"它不是由Hibernate创建的。该表(由应用程序)假定已经存在。
答案 0 :(得分:0)
JPA实现倾向于在提交之前将刷新延迟到DB。你确定即使在提交时也没有完成INSERT
吗?您可以在flush()
方法结束时尝试initialize()
吗?由于这种延迟,如果你想要捕获一些JPA异常并在内部处理执行DML的同一事务,则需要flush()
。
<强>更新强>
正如zbigniewTomczak在评论中所说,initialize()
应该是交易性的。问题在于我不确定Spring是否会在init-method中遵守@Transactional
注释。您可以尝试使用它,因为它是更简单的选项,如果它不起作用,那么您可以在initialize()
中尝试编程式事务管理(完全手动或使用TransactionTemplate
):阅读{{3} }