简体   繁体   English

结合使用JPA的最佳方法

[英]Best way to use JPA with relationships

When I have an Entity with relationships I don't know which is the best way to save changes to DB. 当我有一个带有关系的实体时,我不知道哪种是将更改保存到数据库的最佳方法。

Here is a simplified entity. 这是一个简化的实体。 Please consider I have made little changes to the code to post it here and I can have introduced some errors. 请考虑我对代码进行了很少的更改以将其发布到此处,并且我可能已经引入了一些错误。

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;

As you can see it is linked to other 2 entities with a OneToMany and OneToOne relationships. 如您所见,它通过OneToMany和OneToOne关系链接到其他2个实体。 I'm using Glassfish with jta so transactions and entityManagers are managed by the container. 我将Glassfish与jta一起使用,因此事务和entityManagers由容器管理。

At a time I have a detached (JPA terminology) Permessitemporanei instance in memory. 一次我在内存中有一个独立的(JPA术语)Permessitemporanei实例。 I have to persist the following changes to the database: 1- the associated ingressiconpermesso must be deleted 2- a new ingressiconpermesso must be created 3- statopermesso field must be updated 4- a new Accessiconpermesso must be added to the collection accessiconpermessoCollection 我必须对数据库进行以下更改:1-必须删除关联的ingressiconpermesso 2-必须创建新的ingressiconpermesso 3-必须更新statopermesso字段4-必须将新的Accessiconpermesso添加到集合accessiconpermessoCollection

Which is the best way of doing so ? 哪种方法最好? Perhaps I can do all necessary changes in the Permessitemporanei instance an merge it but I had many troubles doing so and start to think it is not the right side of the relationships to persist changes. 也许我可以在Permessitemporanei实例中进行所有必要的更改并合并它,但是这样做有很多麻烦,并且开始认为坚持更改不是正确的关系。 For me it more natural to save an object at a time, so eliminating all those cascade = CascadeType.ALL. 对我而言,一次保存一个对象更自然,因此消除了所有那些层叠= CascadeType.ALL。

Suppose my Permessitemporanei instance is called 'permesso' ; 假设我的Permessitemporanei实例称为“ permesso”; my code is something like this: 我的代码是这样的:

  1. getEntityManager().remove(permesso.ingressiconpermesso); getEntityManager()。remove(permesso.ingressiconpermesso);
  2. getEntityManager().persist(a new Ingressiconpermesso ); getEntityManager()。persist(一个新的Ingressiconpermesso);
  3. getEntityManager().merge(permesso) // once its statopermesso field has been updated; getEntityManager()。merge(permesso)//一旦其statopermesso字段已更新;
  4. getEntityManager().perist(a new Accessiconpermesso ); getEntityManager()。perist(一个新的Accessiconpermesso);

Obviously this way I have to manually update the in memory 'permesso' with all the changes I made on Database. 显然,以这种方式,我必须使用在数据库上所做的所有更改来手动更新内存中的“ permesso”。

Is there a better approach ? 有更好的方法吗?

By the way all the JPA relationships I have seen are bidirectional. 顺便说一下,我看到的所有JPA关系都是双向的。 Can I make them unidirectional ? 我可以使它们单向吗? To put it in other words can I safely eliminate Code: 换句话说,我可以安全地删除代码:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "iDpermesso") private Collection accessiconpermessoCollection; @OneToMany(cascade = CascadeType.ALL,mappingBy =“ iDpermesso”)私有集合accessiconpermessoCollection;

from the Permessitemporanei entity preserving it on the Accessiconpermesso entity or do i break JPA ? 从Permessitemporanei实体保存在Accessiconpermesso实体上,还是我违反了JPA?

Thanks Filippo 谢谢菲利波

The way I like to approach complex entity updates is to: 我喜欢进行复杂实体更新的方式是:

  1. Start a new transaction. 开始新交易。
  2. Make all the changes that I want to make against my Objects in memory. 对内存中的对象进行所有想要更改的更改。
  3. Tell the EntityManager what I did once I'm done. 告诉EntityManager完成后我做了什么。
  4. Commit the transaction. 提交交易。

But first things first, you will likely have a much easier time of things if you get a non-detached Permessitemporanei instance to start with: 但是首先,如果您获得一个非分离的Permessitemporanei实例开始,那么您可能会更轻松地完成事情:

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

Then do all of your changes in memory, inform the EntityManager , and commit the transaction: 然后在内存中进行所有更改,通知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();

To answer your other question, no, you generally do not need to annotate both sides of a relationship. 要回答另一个问题,不,您通常不需要注释关系的双方。 You can remove your @OneToMany annotation if you want, and it shouldn't break anything (as far as JPA cares, anyways...you may well have application code that relies upon this Collection being present and properly populated, and removing the JPA mapping will of course break any such code). 您可以根据需要删除@OneToMany批注,并且它不会破坏任何内容(就JPA而言,无论如何...您可能会拥有依赖于此Collection并正确填充的应用程序代码,并且删除了JPA映射当然会破坏任何此类代码)。 However, I don't really think you gain anything by removing it, so I'd recommend leaving it alone. 但是,我真的不认为您可以通过删除它来获得任何收益,因此建议您不要理会它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM