[英]JAVA JPA updating the related entities
我在更新相关实体时遇到问题。
让我从一个简单的例子开始。 假设我有一个User 1:1 Profile关系。
如何更新(替换)属于User的Profile实体?
我尝试了以下失败的尝试(OneToOne关系都有CascadeType = ALL属性)
em.getTransaction().begin();
1.User.setProfile(Profile)
....
2.User.setProfile(Profile)
Profile.setUser(User)
.....
3.em.remove(User.getProfile())
User.setProfile(Profile)
Profile.setUser(User)
em.getTransaction().commit();
我对JPA完全感到困惑,有一些有用的示例,但它们与更新实体无关(仅更新单个值,提高薪水等)。
我希望所建议的方法在1:N关系的情况下也能适用。
我总是做em.merge(user);
更新实体后。 如果您有适当的级联选项,这也会更新所有相关的实体。
现在,我知道(听说)该实体应该在事务结束时更新数据库本身,但是我更喜欢直接打电话。 坦率地说,我发现整个“自动更新实体”模式在现实世界开发中更多的是问题而不是优势。
这取决于您想做什么。 如果User和Profile是真正一对一的,那么用一个不同的Profile对象替换整个Profile对象的整个想法有点多余。 如果使用的框架在整个操作中都保留了持久性上下文,则可以仅更新 Profile对象中的值并进行刷新,因为级联会导致创建新对象有些混乱。
但是,如果您的框架没有保留Persistence Context,那么您将拥有已被修改的分离实体,您必须使用em.merge()
或获取原始实体( em.find
)并复制在IMO中,如果给定正确使用JPA的框架,这将很繁琐,容易出错且不必要。 最好在持久性上下文中修改对象,然后让“自动更新实体”来完成任务(显然,我非常喜欢)。 这需要一点时间来适应,但是一旦您习惯了,就永远不会回头。
无论如何,在调用em.flush()
时,所有更改都将写到JDBC连接中,并且在事务完成时将提交连接中的未决更改。
如何更新(替换)属于用户的Profile实体?
由于关联是双向的,因此您必须管理User
和Profile
之间的链接的两端。 因此,“更改”用户的个人资料将需要以下内容:
User user = em.find(User.class, key);
Profile profile = new Profile();
...
user.setProfile(profile);
profile.setUser(user);
em.getTransaction().commit();
使用我使用的JPA实现,已经对上述代码执行了以下查询:
INSERT INTO CPROFILE (ID) VALUES (?)
bind => [2]
UPDATE CUSER SET CPROFILE_ID = ? WHERE (ID = ?)
bind => [2, 1]
我删除了CascadeType ALL,一切都按预期运行,代码如下
......................... CPROFILE
@Entity
public class CProfile {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key id;
private String phone;
@OneToOne(mappedBy="profile")
private CUser User;
......................... CUSER @Entity public class CUser { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Key id; private String email;
@OneToMany(mappedBy="user")
private List<CPossibility> Possibilities = new ArrayList<CPossibility>();
@OneToOne
@JoinColumn(name="cprofile_id")
private CProfile profile;
......................... CREATE ... CUser User = em.find(CUser.class, UserId_); ...
em.getTransaction().begin(); try { Profile_.setUser(User); User.setProfile(Profile_);
em.persist(Profile_);
em.getTransaction().commit();
}
catch(Exception e){GAEHelper.getLogger().warning("Exception:"+e.getMessage()+" "+e.getCause());}
finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
}
em.close();
return true;
}
......................... UPDATE
... CUser User = em.find(CUser.class, UserId_); ... em.getTransaction().begin(); try { em.remove(User.getProfile());
Profile_.setUser(User);
User.setProfile(Profile_);
em.persist(Profile_);
em.getTransaction().commit();
}
多谢你们 !
卡萨巴
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.