请analize以下两个代码,并告诉我,为什么这样做时提交的第一个失败,并主键冲突,而第二个简化版,。这在失败JPA合并删除查询失败后
代码提交:
try{
Query q = em.createQuery("DELETE FROM Puntaje");
q.executeUpdate();
//em.getTransaction().commit();
//em.getTransaction().begin();
Iterator it = l.iterator();
while(it.hasNext()){
DataPuntaje dp = (DataPuntaje)it.next();
Cliente c = new Cliente(dp.getCliente());
Puntaje p = new Puntaje(dp.getPuntaje(),c);
c.agregarPuntaje(p);
em.merge(c);
}
System.out.println("test1");
em.getTransaction().commit();
System.out.println("test2");
}
代码工作正常:
try{
Query q = em.createQuery("DELETE FROM Puntaje");
q.executeUpdate();
em.getTransaction().commit();
em.getTransaction().begin();
Iterator it = l.iterator();
while(it.hasNext()){
DataPuntaje dp = (DataPuntaje)it.next();
Cliente c = new Cliente(dp.getCliente());
Puntaje p = new Puntaje(dp.getPuntaje(),c);
c.agregarPuntaje(p);
em.merge(c);
}
System.out.println("test1");
em.getTransaction().commit();
System.out.println("test2");
}
唯一的区别是,第一个没有犯被删除查询,而是提交它一起最后。 Cliente和Puntaje是级联= ALL的1:N双向关系。 所有插入的Cliente实例都有相同的ID,但合并应该足够聪明,以便在第一个实例被保留后更新而不是插入,但是在第一个实例中似乎失败了,我找不到任何解释。 也即时使用H2嵌入式数据库。
此外,我想补充,第一个代码工作正常,如果有一个已插入Cliente值,这在表实际上是空的,所以删除实际上什么都不做失败。
这是错误即时得到:
Internal Exception: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_5 ON PUBLIC.CLIENTE(NICK)"; SQL statement:
INSERT INTO CLIENTE (NICK) VALUES (?) [23505-169]
Error Code: 23505
Call: INSERT INTO CLIENTE (NICK) VALUES (?)
bind => [cbaldes]
Query: InsertObjectQuery([email protected])
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.0.2.v20100323-r6872): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_5 ON PUBLIC.CLIENTE(NICK)"; SQL statement:
INSERT INTO CLIENTE (NICK) VALUES (?) [23505-169]
Error Code: 23505
Call: INSERT INTO CLIENTE (NICK) VALUES (?)
bind => [cbaldes]
Query: InsertObjectQuery([email protected]
)
这些都是表:
@Entity
public class Puntaje implements Comparable, Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private int total;
@ManyToOne(cascade=CascadeType.ALL, optional = false)
@JoinColumn(name="NICK")
private Cliente cliente;
@Entity
public class Cliente implements Serializable {
@Id
private String nick;
@OneToMany(cascade=CascadeType.ALL, mappedBy="cliente")
private List<Puntaje> puntajes;
你收到一个主键冲突的“Cliente”或“Puntaje”?你可以发布你的stacktrace吗? – Sashi
是的,主键异常,似乎它不够聪明,只能插入一次,然后更新所有其余的,它试图插入每一个合并,这是奇怪的,因为删除什么都不做,它只是失败。 – user1777914