Jpa 同时保存一个实体的两个版本
我目前正试图在JSF/Primefaces中实现一个CRUD应用程序für Orders/Articles 每当我创建一篇文章的新版本时,我都希望合并具有不同状态的旧实体,并使用新ID保存由表单输入填充的新实体 这是商品和订单行之间的关系: 物品实体具有以下字段:Jpa 同时保存一个实体的两个版本,jpa,entity,Jpa,Entity,我目前正试图在JSF/Primefaces中实现一个CRUD应用程序für Orders/Articles 每当我创建一篇文章的新版本时,我都希望合并具有不同状态的旧实体,并使用新ID保存由表单输入填充的新实体 这是商品和订单行之间的关系: 物品实体具有以下字段: @OneToMany(cascade = CascadeType.ALL, mappedBy = "fkArticleID") @XmlTransient private Collection<OrderLine> or
@OneToMany(cascade = CascadeType.ALL, mappedBy = "fkArticleID")
@XmlTransient
private Collection<OrderLine> orderLineCollection;
一开始一切似乎都很顺利。。但是,本文的较新版本似乎会自动创建另一个订单行,该订单行显示在现有订单中。。因此,每当我“更新”一篇文章时,在创建新版本的同时,它也在创建另一个订单行。。我怀疑错误在于文章实体中的@OneToMany字段。。我试图在持久化之前将orderLineCollection设置为null,但它似乎不起作用。您必须删除orderLineCollection上的级联。 如果您保存一篇文章,您将始终获得现有订单行的副本
请考虑删除文章和订单之间的双向关系。通常,您只需要从订单行到文章的单向关系。如果您需要一篇文章的所有订单行,可以使用NamedQuery。谢谢!解除关系解决了问题
public void edit(Article article) throws OptimisticLockException {
/* PK des Auftrags/der Auftragsposition speichern um die Suche zu vereinfachen */
int articleID = article.getArticleID();
/**
*
* Falls sich article im Zustand "detached" befindet, werden in
* attachedArticle die aktuellen Daten aus der DB geladen.
*
* Falls sich orderLine im Zustand "managed" befindet, werden in
* attachedOrderLine die Daten aus dem PersistenceContext geladen. Dies
* ist notwendig, da nur Datensätze für Entities gesperrt werden können
* die sich im Zustand "managed" befinden.
*
*/
Article attachedArticle = em.find(Article.class, articleID, LockModeType.OPTIMISTIC);
/* Prüfen ob der Artikel noch in der Datenbank vorhanden ist */
if (attachedArticle != null) {
/* Laden des aktuellsten Datensatzes aus der Datenbank */
Article latestVersionArticle = findLatestVersion(articleID);
/* Anhand der Version wird geprüft ob die bearbeiteten Daten noch konsistent mit dem Zustand der Datenbank sind */
if (latestVersionArticle.getVersion() == article.getVersion()) {
/**
* Schreibt den bearbeiteten Artikel zurück in die Datenbank,
* Versionsnummer wird am Ende der Transaktion automatisch
* inkrementiert (optimistische Sperre)
*/
latestVersionArticle.setArticleStatus(ArticleStatus.GESPERRT);
em.merge(latestVersionArticle);
/**
* Erstellt einen neuen Artikel mit den eingegebenen Daten und
* dem Status Freigegeben.
*/
article.setArticleStatus(ArticleStatus.FREIGEGEBEN);
article.setOrderLineCollection(null);
em.persist(article);
} else {
/* OptimisticLockException werfen falls die Daten des Auftrags nicht mehr konsistent sind */
throw new OptimisticLockException(article);
}
} else {
throw new OptimisticLockException(article);
}
}