Java – JPA error: duplicate key error during persistent relationship
•
Java
Hello
Thank you in advance
public static interface YY { Object id(); } @Entity @Access(AccessType.FIELD) @Table(name = "X") public class X implements YY { @Id long id; protected X() { this.id = Test.orderId++; } @Override public Long id() { return id; } } public class YPK { private final Date date; private final Long x; public YPK(X x,Date date) { this.date = date; this.x = x.id(); } @Override public boolean equals(Object arg0) { if (arg0 == this) { return true; } else if (arg0 instanceof YPK) { return date.equals(((YPK) arg0).date) && x.equals(((YPK) arg0).x); } return false; } @Override public int hashCode() { return date.hashCode() ^ x.hashCode(); } } @Entity @Access(AccessType.FIELD) @Table(name = "Y") @IdClass(YPK.class) public class Y implements YY { @Id @Temporal(TemporalType.TIMESTAMP) Date date; @Id @ManyToOne(cascade = CascadeType.ALL) private X x; public Y(X x) { this.x = x; date = new DateTime().toDate(); } protected Y() { } @Override public YPK id() { return new YPK(x,date); } } public class Test { public static long orderId = 0; public static long customerId = 0; public static void main(String[] args) { Map<String,String> properties = new HashMap<String,String>(){ { put("javax.persistence.jdbc.url","jdbc:derby://localhost:1527/myDB;create=false;"); put("javax.persistence.jdbc.driver","org.apache.derby.jdbc.ClientDriver"); put("javax.persistence.jdbc.user","myDbUser"); put("javax.persistence.jdbc.password","passwd"); // put(""eclipselink.ddl-generation","drop-and-create-tables"); put(""eclipselink.ddl-generation","none"); } }; EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit",properties); final EntityManager em = emf.createEntityManager(); X x = new X();; saveItem(em,X.class,x); Y y = new Y(x);; Y y2 = new Y(x);; saveItems(em,Y.class,Arrays.asList(y,y2)); saveItems(em,y2)); Z z = new Z(y2);; saveItems(em,Z.class,Arrays.asList(z)); } private static <T extends YY> void saveItem(final EntityManager em,Class<T> clazz,T item) { synchronized(em) { EntityTransaction tx = em.getTransaction(); saveItem(em,clazz,item,tx); } } private static <T extends YY> void saveItems(final EntityManager em,Collection<T> items) { synchronized (em) { EntityTransaction tx = em.getTransaction(); try { tx.begin(); for (T item : items) { saveItem(em,tx); } tx.commit(); } finally { if (tx.isActive()) { tx.rollback(); } } } } private static <T extends YY> void saveItem(final EntityManager em,T item,EntityTransaction tx) { Object id = item.id(); T existing = em.find(clazz,id); if (existing != null) { em.merge(item); } else { em.persist(item); } }
}
I run the program once, "drop and create tables" uncomment, and everything is normal because there is no X entry in the database I commented out drop - and - create - tables and ran it again, but this time I got the following error thank you
[EL Warning]: 2011-03-24 06:52:56.047--UnitOfWork(20391510)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.sqlIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'sql110324065226450' defined on 'X'. Error Code: -1 Call: INSERT INTO X (ID) VALUES (?) bind => [1 parameter bound] Query: InsertObjectQuery(com.test.X@1b6101e) Exception in thread "main" javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: java.sql.sqlIntegrityConstraintViolationException: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'sql110324065226450' defined on 'X'. Error Code: -1 Call: INSERT INTO X (ID) VALUES (?) bind => [1 parameter bound] Query: InsertObjectQuery(com.test.X@1b6101e) at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102) at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63) at com.test.Test.saveItems(Test.java:80) at com.test.Test.main(Test.java:56)
Here is the log: 1st run successful 2nd run failure
Solution
Notice you're on the phone,
saveItems(em,y2));
twice? Is there an error on the first or second call?
Please include your best login
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
二维码