JPA / Spring重复输入密钥' PRIMARY'

时间:2016-06-23 10:02:18

标签: spring jpa one-to-many transactional

我有问题,JPA。

我的保存方法标记为@Transactional,如下所示:

        @Transactional(propagation = Propagation.REQUIRED)
        public void push(long id) {
            Parent parent = dao.findParentById(id);
            setParentMeta(parent);
            Country country = dao.findCountry(id);
            setParentChild(parent);
            User user = dao.findUser(id);
            dao.update(parent);
        }

        public void setParentMeta(Parent parent){
            parent.setTitle("toto");
            parent.setdescription("some description");
        }

        public void setParentChild(Parent parent){
            List<Child> childList = new ArrayList<>();
            for (String date : dao.getList()) {
                Child child = new Child();
                ChildPK childPK = new ChildPK();
                childPK.setProductId(parent.getId());
                childPK.setDate(date);
                child.setChildPK(childPK);
                child.setParent(parent);
                childList.add(child);
            }
            parent.setChildList(childList);
        }

我的父母实体:

        public class Parent {
            ...
            private long parentId;
            @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent", fetch = FetchType.LAZY, orphanRemoval = true)
            private List<Child> childList;
            ...
        }

我的孩子实体:

        public class Child {
            ...
            @EmbeddedId
            protected ChildPK childPK;
            @MapsId("parentId")
            @ManyToOne(optional = false, fetch = FetchType.LAZY)
            @JoinColumn(name = "parent_id", referencedColumnName = "parent_id", insertable = true, updatable = true)
            private Parent parent;
            ...
        }
        @Embeddable
        public class ChildPK {
            ....
            @Basic(optional = false)
            @Column(name = "parent_id")
            private long parentId;
            @Basic(optional = false)
            @Column(name = "date")
            @Temporal(TemporalType.TIMESTAMP)
            private Date date;
            ....
        }

我的问题是当我从方法&#34; push&#34;删除@Transactional(propagation = Propagation.REQUIRED)时并把它放在dao所有插入/更新或rallback工作完美:

        @Transactional(propagation = Propagation.REQUIRED)
        public E update(E entity) {
            return entityManager.merge(entity);
        } 

但是如果我把这个注释放在push方法中并从dao中删除它我得到这个例外:

        Duplicate entry '3623238-2016-02-21 00:00:00' for key 'PRIMARY'
        Error Code: 1062
        Call: INSERT INTO child (date, parent_id) VALUES (?, ?)
            bind => [2016-02-21 00:00:00.0, 3623238]

这里的问题是eclipselink在孩子改变时自动冲洗。 有一个为什么要在推送方法结束时进行刷新?

2 个答案:

答案 0 :(得分:0)

当你试图保持对象已经存在时会发生这个错误,另一方面,@ Transactal(propagation = Propagation.REQUIRED)使用已经打开的事务并在没有人打开时打开新的事务,我认为问题使用 findByParentId 方法,因此请尝试&#34;找到&#34;它然后发送推送方法。

答案 1 :(得分:0)

我发现了问题。 事务管理器配置不正确the solution with code example