【问题标题】:JPA/Spring Duplicate entry for key 'PRIMARY'键'PRIMARY'的JPA / Spring重复条目
【发布时间】:2016-10-25 14:21:24
【问题描述】:

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

我的问题是当我从方法“push”中删除 @Transactional(propagation = Propagation.REQUIRED) 并将其放入 dao 中时,所有插入/更新或回滚都可以正常工作:

        @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 在子更改时自动刷新。 有一个为什么要在 push 方法结束时刷新?

【问题讨论】:

    标签: spring jpa one-to-many transactional


    【解决方案1】:

    我发现了问题。 这里的事务管理器配置不好是the solution with code example

    【讨论】:

      【解决方案2】:

      当你试图持久化已经存在的对象时会发生这个错误,另一方面,@Transactional(propagation = Propagation.REQUIRED) 使用已经打开的事务并在没有打开的时候打开新的,我认为问题使用 findByParentId 方法,因此请尝试“找到”它,然后将其发送到 push 方法。

      【讨论】:

      • 我无法将 findByParentId 放在推送方法之外
      • 请说明您为什么不能这样做?
      • 因为改变了任何东西,下面也有一些 find 案例,这里的问题是如果我删除所有 find 并直接调用更新该工作。对于我的治疗,我需要在保存之前找到
      • 这里您需要为现有的 Parent 保存新的 Childs 吗?
      • 请检查子表中的列(ID)是否为auto_increment
      猜你喜欢
      • 2019-04-04
      • 2021-06-10
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 2012-07-23
      • 2013-09-30
      相关资源
      最近更新 更多