我随机得到以下例外:org.eclipse.persistence.exceptions.ValidationException Exception Description: The attribute [id] of class [domain.Person] is mapped to a primary key column in the database. Updates are not allowed.
如何避免在与jpa使用manytomany关系时出现ValidationException?
执行“deleteAllPersons()”时主要抛出异常。当两个实体之间存在必须删除的链接时,就会出现该错误,并且似乎发生在第二个被删除的人身上。
值得注意的是,错误通常不会在调试模式下出现,也不会在测试套件自行运行时出现。这导致我认为问题可能与时间有关,或者原因是在某些情况下在导致任何问题之前自动解决的不一致。
public void deleteAllPersons(){
for(Person person: getAllPersons()){
long id = person.getId();
deletePerson(id);
}
与deletePerson的(ID)方法是
public void deletePerson(long id) {
Person person = getPerson(id);
List<OrderBill> ordersToBeUnlinked = new ArrayList<>();
ordersToBeUnlinked.addAll(person.getOrders());
for (OrderBill order : ordersToBeUnlinked) {
person.removeOrder(order);
System.out.println(order + "deleted");
}
try{
manager.getTransaction().begin();
manager.merge(person);
} catch (Exception e1){
throw new DbException("Error merging person" + person + "\n" + e1.getMessage(), e1);
}
try {
manager.remove(person);
manager.flush();
manager.getTransaction().commit();
} catch (Exception e){
manager.getTransaction().rollback();
throw new DbException("error deleting " + person + "\n" + e.getMessage(), e);
}
}
合并去罚款,但在删除会抛出异常。 在异常消息,我可以看到人在它没有更多订单的名单
在情况下,我在个人或OrderBill类犯了一个错误, 下面是这两个类的最重要的部分:
人
@Entity(name="Person")
public class Person {
@Id
@Column(name="PERSON_ID")
@GeneratedValue
private long id;
@ManyToMany(mappedBy="authors", fetch=FetchType.LAZY, cascade={CascadeType.MERGE})
private Set<OrderBill> orders;
@Column(name="name")
private String name = "undefined";
public Person(String name){
setName(name);
payments = new HashSet<Payment>();
orders = new HashSet<OrderBill>();
}
public void removeOrder(OrderBill order){
orders.remove(order);
if(order.getAuthors().contains(this)){
order.removeAuthor(this);
}
}
OrderBill:
@Entity(name="OrderBill")
@NamedQueries({
@NamedQuery(name="Order.getAll", query="select o from OrderBill o"),
@NamedQuery(name="Order.findOrders", query="select o from OrderBill o join o.orderWeek as w where (w.weekNr = :w and w.yearNr = :y)")
})
public class OrderBill implements Transaction{
@Id
@Basic(optional = false)
@NotNull
@Column(name="ORDER_ID")
@GeneratedValue
private long id;
@ManyToMany
@JoinTable(
name="ORDER_PERSON",
[email protected](name="ORDER_ID"),
[email protected](name="PERSON_ID")
)
private Set<Person> authors;
public OrderBill(double totalCost, int weekNr, int yearNr){
setOrderWeek(new OrderWeek(weekNr, yearNr));
setTotalCost(totalCost);
authors = new HashSet<>();
}
public void removeAuthor(Person author){
authors.remove(author);
if(author.getOrders().contains(this))
author.removeOrder(this);
}
这是一种双向关系,因此当您去删除一个人时,您还需要从任何OrderBill实例中删除对该人员实例的所有引用。其中之一是引用它,导致下一个事务的持久性单元出现错误。 – Chris