合并有时在 JPA Hibernate 中失败,但在同一事务中 PERSIST 有效
Posted
技术标签:
【中文标题】合并有时在 JPA Hibernate 中失败,但在同一事务中 PERSIST 有效【英文标题】:Merge fails sometime in JPA Hibernate but in same transaction PERSIST works 【发布时间】:2016-05-09 12:14:28 【问题描述】:我已经按照我的理解经历了分离和附加的实体
User user=entityManager.find(User.class,1);
这里的用户是一个附加实体,对此的任何更改都将反映在数据库中
而分离的实体是新创建的实体,您可以使用合并而不是通过以下方式持久化@
User userDetached=new User;
user.setID(1);
User userattahed=entityManger.merge(userDetached);
userattahed.setName("cool");
这里的名字会反映在数据库中...如果我没记错的话
下面是我的代码,其中几次 (100/10) 合并不起作用,而坚持 100% 起作用...
entityManager = JPAUtil.getEntityManager();
UsersModel user=entityManager.find(UsersModel.class,getMobile_num());
TrackModel track=new TracksModel();
user.setBalance(user.getBalance().add(getAmount()));
track.setMobile_Num(getMobile_num());
track.setTransaction_Type(getTransaction_Type());
track.setAmount(getAmount());
entityManager.merge(user);//doesn't update few times
entityManager.persist(track); //works 100%
JPAUtil.commit();
【问题讨论】:
为什么要合并处于“托管”状态的实体?毫无意义,因为更新将是“已知的”。 @NeilStockton 我明白你的意思,但它有什么影响吗?? 这意味着你的调用是没有意义的(就像在不同的对象上使用持久化一样毫无意义)。如果您想调试您的问题,那么您可以查看日志以了解您选择的 JPA 提供程序。 【参考方案1】:这行有点奇怪:
user.setBalance(user.getBalance().add(getAmount()));
这是您实际对用户进行的唯一更改。它有什么作用?什么是余额,添加有什么作用?在某些情况下可能根本没有变化,所以没有什么可存储的。
由于它无论如何都在会话中(它之前已加载),因此您无需调用任何东西来持久化它。最迟将在提交时刷新。
还请注意,当您调用persist of merge 或类似的方法时,更改不一定会刷新到数据库中。它可能会在提交时刷新。因此,在您决定刷新什么之前,请始终将事务运行到结束。
【讨论】:
感谢您的回复...Balance 属性是 BigDecimal 数据类型...。我需要将 Amount(getAmount) 添加到用户当前余额,所以我这样做 user.setBalance(user. getBalance().add(getAmount())); Amount 仍然可能是零?您如何确定“它是否有效”? 你看到 track.setAmount(getAmount());在数据库中获取 PERSIST 的行...告诉最后一笔交易 AMOUNT 是这个 track.getAmount【参考方案2】:我遇到了类似的问题,即持续存在和合并失败;这是破坏的代码示例:
public MyType persistMyType(MyType myType)
MyType merge = em.merge(myType);
em.persist(merge);
return merge;
一旦我删除了合并,我就再也没有这个问题了。
PS:MyType 是 MyParent 的子对象,其注释如下:
@OneToMany(mappedBy="myParent", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
我很高兴找到了解决方法,但我仍然不知道出了什么问题。我倾向于认为这个问题与脏物有关。 SQL 日志记录显示在持久化之前发生的大量 SELECT,这可以让您了解 hibernate 正在做什么。
【讨论】:
以上是关于合并有时在 JPA Hibernate 中失败,但在同一事务中 PERSIST 有效的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JPA 和 Hibernate 设置默认查询超时?
jpa在save失败后service端catch不到异常原因(Hibernate的一级缓存)
Cascade保存子实体失败了JPA(Spring数据+ Hibernate)?