我有问题,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在孩子改变时自动冲洗。 有一个为什么要在推送方法结束时进行刷新?
答案 0 :(得分:0)
当你试图保持对象已经存在时会发生这个错误,另一方面,@ Transactal(propagation = Propagation.REQUIRED)使用已经打开的事务并在没有人打开时打开新的事务,我认为问题使用 findByParentId 方法,因此请尝试&#34;找到&#34;它然后发送推送方法。
答案 1 :(得分:0)
我发现了问题。 事务管理器配置不正确the solution with code example