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

标签 java jsf jpa netbeans ejb

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

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

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- 必须删除关联的 ingressiconpermesso 2- 必须创建一个新的 ingressiconpermesso 3- 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/

相关文章:

java - 在 Spring boot/Spring Data MongoDB 中找不到存储库 bean

java - 在 glassfish 上部署 JSF 应用程序时出错

java - p :commandButton inside p:pdataTable/p:dataGrid/ui:repeat does not invoke method

java - EntityManager 数据传输到 mySQL 时出现 UTF-8 编码问题

java - 无法访问 TransactionManager 或 UserTransaction 来进行物理事务委托(delegate)

java - Robolectric::LayoutInflator.inflate() 卡在 onCreateOptionsMenu 中

java - 在 Fedora 中 jmyron 不支持

javascript - <p :slider> causes JS error "TypeError: h is undefined"

java - EclipseLink 错误 : Entity class has no primary key specified. 它应该定义 @Id、@EmbeddedId 或 @IdClass

java - 在java中的函数构造函数中使用数组