Hello, I remember having a similar problem when I first started my current project 2 years ago.
I found that if I assigned the id / version fields with zero, I would get an error. However, if I checked the value of these fields and made the assignment only when they were NOT zero jpa accepted them! IOW - JPA seemed to be aware of whether the fields were assigned a default value from the JVM or whether I specifically did so. If I did, jpa wanted to use my values, if the JVM did then jpa generates the value while persisting. tl;dr try creating a new Object and only populate the id / version field if the value is NOT zero. John > -----Original Message----- > From: Krishnaprasad Subbarao [mailto:[email protected]] > Sent: Wednesday, February 20, 2013 2:38 PM > To: [email protected] > Subject: Re: Fw: Error in EntityManager.persist () if the database already > contains a row with id=0 > > Hello Kevin/Albert, > > Thanks for suggestions. I added initial-value attribute to the sequence > generator mapping in the test program attached earlier, but the same > exception is thrown. > > The new sequence generator mapping is as follows, > > <id name="id"> > <column name="Id"/> > <generated-value strategy="SEQUENCE" generator="PART_SEQ"/> > <sequence-generator name="PART_SEQ" sequence-name= > "PART_SEQ" allocation-size="1" initial-value="100"/> > </id> > > The initial-value 100 specified in the mapping is not present in the database. > > I am not sure if I understand this issue well, but it seems OpenJPA is > checking > for duplicate id before actually reading a value from the given sequence and > populating it in the object to be persisted. When the duplicate check is done, > the id field has default value "0", the database already has a row with id=0, > so > the duplicate check fails. When there is no row in the database with id=0 the > duplicate check succeeds, after that, the sequence is used to populate the > correct id value before persisting the record. > > By removing the database row with id=0, a row was successfully added in the > database of this example as well as in my application. But since we have > business logic around rows with id=0, we wish to avoid changing the business > logic and keep it as a last option. > > > Thanks and Regards, > > KRISHNAPRASAD SUBBARAO > > > > > From: Kevin Sutter <[email protected]> > To: [email protected], > Date: 02/19/2013 11:32 PM > Subject: Re: Fw: Error in EntityManager.persist () if the database > already contains a row with id=0 > > > > Are you indicating that if you remove the PART record with an id of 0 from > the database, then everything works just fine? But, if you leave this initial > PART record with an id of 0, then you get the duplicate key exception? If > that's the case and this PART with an id of 0 has to be part of the dataset, > then why not just start the id generation with a larger number? (That's what > Albert's suggestion was, but he only replied to the dev list. BTW, if you > post > to multiple lists, then you need to monitor multiple lists. It's just part of > the > game. Thanks.) > > Kevin > > On Tue, Feb 19, 2013 at 2:50 AM, Krishnaprasad Subbarao < > [email protected]> wrote: > Attaching a smaller size example to due attachment size issues. > > I am using OpenJPA 2.2.1. I request you to copy the openjpa-all-2.2.1.jar and > the database driver in to the lib folder before executing the sample. > > > Thanks and Regards, > > KRISHNAPRASAD SUBBARAO > > Software Developer, Cloud Platform (BSS), Industry Solutions, India > Software Lab > > > Phone: 91-20-40117370 | Mobile: 91--9096009911 > E-mail: [email protected] > Chat: [email protected] > Find me on: and within IBM on: > > > Tech Park One (panchshill) > Pune, MH 411006 > India > > > ----- Forwarded by Krishnaprasad Subbarao/India/IBM on 02/19/2013 02:12 > PM > ----- > > From: Krishnaprasad Subbarao/India/IBM > To: [email protected], > Cc: users <[email protected]> > Date: 02/19/2013 01:54 PM > Subject: Re: Error in EntityManager.persist () if the database > already contains a row with id=0 > > > Hello Rick/Kevin, > > Thanks for your suggestions. > > The mapping for com.ibm.wdp.bss.party.entity.PartyObject is defined in > party.orm.xml. This contains a mapping <version name="version"/> for > version field used for optimistic locking. > > Also, I have manually corrected the party.orm.xml to add correct mapping > for <id field. The mapping for Id field defines a sequence generator with > allocation-size=1 as defined below > > <id name="id"> > <column name="Id"/> > <generated-value strategy="SEQUENCE" generator="PART_SEQ"/> > <sequence-generator name="PART_SEQ" sequence-name= > "PART_SEQ" allocation-size="1"/> > </id> > > [attachment "BSS-JPA.zip" deleted by Krishnaprasad Subbarao/India/IBM] > The > attached sample contains a working sample to reproduce the error. The test > database contains a row with id 0 in the table PART. The execution of > JPAAddEntityTest.java fails with the error given in the first mail below. > > The moment I remove the row with id 0 manually from table PART and > re-execute the JPAAddEntityTest.java. Records successfully get inserted in > to PART table and ADDRESS table with appropriate next values from the > sequences. > > I have following assumptions and questions about this issue. > 1. Defining version in the .orm.xml file will not make any difference > as compared to the @version annotation specified in the Bean > 2. Can we configure OpenJPA to use a different default value for > Identity fields say -1 instead of the Java default value 0. A new object > to be persisted in the database will have id attribute set to -1 instead > of 0? > 3. Can we configure OpenJPA to ignore the database row with Primary > Key 0? > > > Thanks and Regards, > > KRISHNAPRASAD SUBBARAO > > Software Developer, Cloud Platform (BSS), Industry Solutions, India > Software Lab > > > Phone: 91-20-40117370 | Mobile: 91--9096009911 > E-mail: [email protected] > Chat: [email protected] > Find me on: and within IBM on: > > > Tech Park One (panchshill) > Pune, MH 411006 > India > > > > > > From: Rick Curtis <[email protected]> > To: users <[email protected]>, > Date: 02/19/2013 01:28 AM > Subject: Re: Error in EntityManager.persist () if the database > already contains a row with id=0 > > > > Could you try adding an @Version field to your Entities? > > Thanks, > Rick > > > On Mon, Feb 18, 2013 at 1:27 PM, Krishnaprasad Subbarao < > [email protected]> wrote: > > > Hello, > > > > Following error occurs while I am trying to persist a record. The id > field > > has been assigned a default value (0) as per the guidelines. > > > > <openjpa-2.2.1-r422266:1396819 fatal store error> * > > org.apache.openjpa.persistence.RollbackException*: An object of type > > "com.ibm.wdp.bss.party.entity.PartyObject" with oid "0" already exists > in > > this context; another cannot be persisted. > > FailedObject: com.ibm.wdp.bss.party.entity.PartyObject@7aa47aa4 > > at org.apache.openjpa.persistence.EntityManagerImpl.commit(* > > EntityManagerImpl.java:594*) > > at com.ibm.test.jpa.JPAAddEntityTest.main(* > > JPAAddEntityTest.java:38*) > > Caused by: <openjpa-2.2.1-r422266:1396819 nonfatal store error> * > > org.apache.openjpa.persistence.EntityExistsException*: An object of type > > "com.ibm.wdp.bss.party.entity.PartyObject" with oid "0" already exists > in > > this context; another cannot be persisted. > > FailedObject: com.ibm.wdp.bss.party.entity.PartyObject@7aa47aa4 > > at org.apache.openjpa.kernel.BrokerImpl.checkForDuplicateId(* > > BrokerImpl.java:5080*) > > at org.apache.openjpa.kernel.BrokerImpl.persistInternal(* > > BrokerImpl.java:2653*) > > at org.apache.openjpa.kernel.BrokerImpl.persist(* > > BrokerImpl.java:2573*) > > at org.apache.openjpa.kernel.BrokerImpl.persist(* > > BrokerImpl.java:2556*) > > at org.apache.openjpa.kernel.SingleFieldManager.preFlushPC(* > > SingleFieldManager.java:800*) > > at org.apache.openjpa.kernel.SingleFieldManager.preFlush(* > > SingleFieldManager.java:621*) > > at org.apache.openjpa.kernel.SingleFieldManager.preFlush(* > > SingleFieldManager.java:589*) > > at org.apache.openjpa.kernel.SingleFieldManager.preFlush(* > > SingleFieldManager.java:505*) > > at org.apache.openjpa.kernel.StateManagerImpl.preFlush(* > > StateManagerImpl.java:3028*) > > at org.apache.openjpa.kernel.PNewState.beforeFlush(* > > PNewState.java:44*) > > at org.apache.openjpa.kernel.StateManagerImpl.beforeFlush(* > > StateManagerImpl.java:1042*) > > at org.apache.openjpa.kernel.BrokerImpl.flush(* > > BrokerImpl.java:2114*) > > at org.apache.openjpa.kernel.BrokerImpl.flushSafe(* > > BrokerImpl.java:2074*) > > at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(* > > BrokerImpl.java:1992*) > > at org.apache.openjpa.kernel.LocalManagedRuntime.commit(* > > LocalManagedRuntime.java:81*) > > at org.apache.openjpa.kernel.BrokerImpl.commit(* > > BrokerImpl.java:1516*) > > at org.apache.openjpa.kernel.DelegatingBroker.commit(* > > DelegatingBroker.java:933*) > > at org.apache.openjpa.persistence.EntityManagerImpl.commit(* > > EntityManagerImpl.java:570*) > > ... 1 more > > > > The reason for this issue I found is, if the database which this object > > being persisted, contains a row with primary key as 0, then adding new > > record fails. Seems a duplicate primary key check is done when default > > value (0) is assigned to the id attribute of type primitive long. A > record > > with Primary Key value = 0 already exists, so duplicate primary key > check > > fails. > > > > This zip file contains a sample code with which I was able to reproduce > > this error. > > > > Adding a row with id=0 before persisting any object throws the error > > mentioned above. > > > > I request all to help in resolving this issue. The id 0 has been in use > > for many days using hibernate. Hence we would like not to change this > row > > in the database. > > > > Also would like to know if there is any config parameter to change the > > default value of the id from 0 to any other value. > > > > > > > > Thanks and Regards, > > > > *KRISHNAPRASAD SUBBARAO* > > Software Developer, Cloud Platform (BSS), Industry Solutions, India > > Software Lab > > > > > > > -- > *Rick Curtis* >
