同时保存2个版本的实体

时间:2017-02-27 08:05:02

标签: jpa entity

我目前正在尝试在JSF / Primefaces中实现CRUD-Application for Fders or Articles。

每当我创建一篇文章的新版本时,我想将旧实体与不同的状态合并,并使用新ID保存由表单输入填充的新实体。

这是Article和OrderLine之间的关系: enter image description here

文章实体具有以下字段:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "fkArticleID")
@XmlTransient
private Collection<OrderLine> orderLineCollection;

这是更新/保存新实体的方法:

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);
        }

    }

一开始似乎一切正常......但是文章的新版本似乎会自动创建另一个OrderLine,它出现在现有的订单中..所以每当我“更新”文章时,在创建新版本时,它还创建了另一个OrderLine ..我怀疑错误在于Article-Entity中的@OneToMany字段..我试图在持久化之前将orderLineCollection设置为null但它似乎不起作用。

1 个答案:

答案 0 :(得分:0)

您必须删除orderLineCollection上的级联。 如果你坚持一篇文章,你将永远得到现有orderLines的重复。

还请考虑删除Article和OrderLine之间的双向关系。通常,您只需要从OrderLine到Article的单向关系。如果您需要文章的所有OrderLines,则可以使用NamedQuery。