gpt4 book ai didi

java - 在关系中使用 JPA 的最佳方式

转载 作者:行者123 更新时间:2023-12-02 00:39:00 25 4
gpt4 key购买 nike

当我有一个具有关系的实体时,我不知道哪种是将更改保存到数据库的最佳方法。

这是一个简化的实体。请考虑一下,我对代码进行了一些更改,以便将其发布到此处,并且我可能会引入一些错误。

public class Permessitemporanei implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "ID_permesso")
private Integer iDpermesso;
@Column(name = "Stato_permesso")
private Integer statopermesso;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "iDpermesso")
private Collection<Accessiconpermesso> accessiconpermessoCollection;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "iDpermesso")
private Ingressiconpermesso ingressiconpermesso;

正如您所看到的,它通过 OneToMany 和 OneToOne 关系链接到其他 2 个实体。我将 Glassfish 与 jta 结合使用,因此事务和实体管理器由容器管理。

有一次,我的内存中有一个独立的(JPA 术语)Permessitetemporanei 实例。我必须将以下更改保留到数据库:1- 必须删除关联的 ingressiconpermesso2- 必须创建一个新的 ingressiconpermesso3- statopermesso 字段必须更新4- 必须将新的 Accessiconpermesso 添加到集合 accessiconpermessoCollection

最好的方法是什么?也许我可以在 Permessitemporanei 实例中进行所有必要的更改并将其合并,但这样做时遇到了很多麻烦,并开始认为持久更改不是关系的右侧。对我来说,一次保存一个对象更自然,因此消除所有那些级联 = CascadeType.ALL。

假设我的 Permessitemporanei 实例名为“permesso”;我的代码是这样的:

  1. getEntityManager().remove(permesso.ingressiconpermesso);
  2. getEntityManager().persist(一个新的 Ingressiconpermesso );
  3. getEntityManager().merge(permesso)//一旦其 statopermesso 字段已更新;
  4. getEntityManager().perist(一个新的 Accessiconpermesso );

显然,这样我必须使用我对数据库所做的所有更改手动更新内存中的“permesso”。

有更好的方法吗?

顺便说一句,我见过的所有 JPA 关系都是双向的。我可以让它们单向吗?换句话说,我可以安全地消除吗?代码:

@OneToMany(级联= CascadeType.ALL,mappedBy =“iDpermesso”) 私有(private)集合 accessiconpermessoCollection;

来自 Permessitetemporanei 实体,将其保留在 Accessiconpermesso 实体上,还是会破坏 JPA?

谢谢菲利波

最佳答案

我喜欢处理复杂实体更新的方式是:

  1. 开始新交易。
  2. 对内存中的对象进行我想要进行的所有更改。
  3. 完成后告诉 EntityManager 我做了什么。
  4. 提交交易。

但首先,如果您从一个非分离的 Permessitemporanei 实例开始,您可能会轻松得多:

Permessitemporanei persistentInstance = em.find(Permessitemporanei.class, detachedInstance.getId());

然后在内存中进行所有更改,通知EntityManager,并提交事务:

//begin a transaction
em.getTransaction().begin();

//remember the old Ingressiconpermesso instance
Ingressiconpermesso oldIngression = persistentInstance.getIngressiconpermesso();

//create a new Ingressiconpermesso instance
Ingressiconpermesso newIngression = new Ingressiconpermesso();
//call newIngression.set...() methods here

//associate the new Ingressiconpermesso with the Permessitemporanei
persistentInstance.setIngressiconpermesso(newIngression);

//update statopermesso
persistentInstance.setStatopermesso(7); //replace '7' with whatever the real value is

//add a new Accessiconpermesso
Accessiconpermesso accession = new Accessiconpermesso();
//call accession.set...() methods here

//associate the Accessiconpermesso with the Permessitemporanei
accession.setPermissitemporanei(persistentInstance);

//now tell the EntityManager what we did
em.remove(oldIngression); //delete the old Ingressiconpermesso
em.persist(newIngression); //add the new Ingressiconpermesso
em.persist(accession); //add the Accessiconpermesso
em.merge(persistentInstance); //update the Permessitemporanei

//commit the transaction
em.getTransaction().commit();

要回答您的另一个问题,不,您通常不需要注释关系的双方。如果需要,您可以删除 @OneToMany 注释,并且它不应该破坏任何内容(就 JPA 而言,无论如何......您很可能拥有依赖于此 Collection 的应用程序代码 存在并正确填充,删除 JPA 映射当然会破坏任何此类代码)。然而,我真的不认为删除它会带来任何好处,所以我建议不要管它。

关于java - 在关系中使用 JPA 的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6897961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com