JPA/Spring 键重复条目 'PRIMARY'
JPA/Spring Duplicate entry for key 'PRIMARY'
我有一个关于 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 all insert/update 或 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]
这里的问题是当 child 改变时 eclipselink 自动刷新。
在 push 方法的末尾有一个为什么要刷新?
当你试图持久化对象已经存在时会发生这个错误,另一方面,@Transactional(propagation = Propagation.REQUIRED) 使用已经打开的事务并在没有打开的时候打开新的,我认为 findByParentId 方法有问题,所以尝试 "find" 它然后将它发送给 push 方法。
我发现了问题。
此处的事务管理器配置不当 the solution with code example
我有一个关于 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 all insert/update 或 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]
这里的问题是当 child 改变时 eclipselink 自动刷新。 在 push 方法的末尾有一个为什么要刷新?
当你试图持久化对象已经存在时会发生这个错误,另一方面,@Transactional(propagation = Propagation.REQUIRED) 使用已经打开的事务并在没有打开的时候打开新的,我认为 findByParentId 方法有问题,所以尝试 "find" 它然后将它发送给 push 方法。
我发现了问题。 此处的事务管理器配置不当 the solution with code example