I think you are right, the new instance is probably created by new() followed by field-by-field copy of the state. But this is how any XML de-serialization works (in this case it is done by Weblogic web service implementation). This use case must be supported, and according to the documentation it should have been.
I made my code working by introducing version id. This is something I had planned to do anyways, so for me it's not a big deal. However, I worked on projects where we had to deal with legacy DB schema that didn't allow us to have version id - and we didn't have a luxury to change the schema to support it. Regards, Aleksandar Likic Pinaki Poddar wrote: > > Hello Aleksandar, >> This use case is so common, I am surprised that nobody had encountered > this problem before. OpenJPA documentation tells me it should be >> possible. > If to be merged instance is a clone created by > serialization+deserialization -- then OpenJPA detects the update even > without any version field and "does the right thing". I think your issue > raised the use case where to be merged instance is a 'copy' of another > persistent object created by Java new() followed by field-by-field copy > of the state. This makes OpenJPA to decide the instance as a new > instance rather than a detached instance. > > However, others may suggest ways to do what your use case requires. > > > Pinaki Poddar > BEA Systems > 415.402.7317 > > > -----Original Message----- > From: Aleksandar Likic [mailto:[EMAIL PROTECTED] > Sent: Tuesday, May 29, 2007 2:08 PM > To: open-jpa-dev@incubator.apache.org > Subject: Re: [jira] Commented: (OPENJPA-245) Attach NEW and > auto-increment identity > > > From the documentation, I don't see that merge() requires a version > field for it to function the way I want. The use case is simple - a web > service that updates an existing record in database which doesn't have > associated version id. This use case is so common, I am surprised that > nobody had encountered this problem before. OpenJPA documentation tells > me it should be possible. > > Here is copy/paste from OpenJPA documentation. Pay attention to the last > bullet point ("If neither of the above cases apply..."). > > 1.2. Attach Behavior > > When attaching, OpenJPA uses several strategies to determine the optimal > way to merge changes made to the detached instance. As you will see, > these strategies can even be used to attach changes made to a transient > instance which was never detached in the first place. > > * If the instance was detached and detached state is enabled, > OpenJPA will use the detached state to determine the object's version > and primary key values. In addition, this state will tell OpenJPA which > fields were loaded at the time of detach, and in turn where to expect > changes. Loaded detached fields with null values will set the attached > instance's corresponding fields to null. > > * If the instance has a Version field, OpenJPA will consider the > object detached if the version field has a non-default value, and new > otherwise. > > When attaching null fields in these cases, OpenJPA cannot > distinguish between a field that was unloaded and one that was > intentionally set to null. In this case, OpenJPA will use the current > detach state setting to determine how to handle null fields: fields that > would have been included in the detached state are treated as loaded, > and will in turn set the corresponding attached field to null. > > * If neither of the above cases apply, OpenJPA will check to see if > an instance with the same primary key values exists in the database. If > so, the object is considered detached. Otherwise, it is considered new. > > > JIRA [EMAIL PROTECTED] wrote: >> >> >> [ >> https://issues.apache.org/jira/browse/OPENJPA-245?page=com.atlassian.j >> ira.plugin.system.issuetabpanels:comment-tabpanel#action_12499851 >> ] >> >> Pinaki Poddar commented on OPENJPA-245: >> --------------------------------------- >> >> >> merge() to identify that the the merged entity instance is not >> *truely* new but a version of a instance that is already persistent, >> the entity requires a version field. >> If the merged instance was a clone created out of serialization and >> desrialization, then OpenJPA will maintain the required bits to >> identify the difference between a truly new instance and an instance >> that has been detached. >> >> >> >>> Attach NEW and auto-increment identity >>> -------------------------------------- >>> >>> Key: OPENJPA-245 >>> URL: > https://issues.apache.org/jira/browse/OPENJPA-245 >>> Project: OpenJPA >>> Issue Type: Bug >>> Components: jpa >>> Affects Versions: 0.9.6, 0.9.7 >>> Environment: jdk1.5.0_11, Win XP, Fedora Core 6, Postgres 8.1 > >>> (on >>> Fedora) >>> Reporter: Aleksandar Likic >>> >>> According to documentation (1.2 Attach Behavior), when an entity >>> instance is NEW (never detached): >>> * If neither of the above cases apply, OpenJPA will check to see >>> if an instance with the same primary key values exists in the >>> database. If so, the object is considered detached. Otherwise, it is > considered new. >>> This doesn't work for me - a new record in database is created on >>> commit instead of updating the existing one. The "regular" case - >>> detach/modify/attach works fine - the existing record is updated. >>> It is very easy to reproduce - just create a new instance of an >>> entity, assign an already existing primary key, call em.merge() and >>> commit. A new record will be created in database, with new, > auto-generated primary key. >>> I stumbled on this trying to implement a web service that uses >>> OpenJPA-based backend. When servicing an "update" request, the web >>> service instantiates a NEW object (by performing XML >>> de-serialization) and calls em.merge to update the entity. A new >>> record gets created instead of updating an existing one. >>> ------------ Entity class (START) ------------------------------ >>> package exaple; public class Consumer implements java.io.Serializable > >>> { >>> private long id; >>> public long getId() { >>> return this.id; >>> } >>> public void setId(long id) { >>> this.id = id; >>> } >>> private java.lang.String firstName; >>> public java.lang.String getFirstName() { >>> return this.firstName; >>> } >>> public void setFirstName(java.lang.String firstName) { >>> this.firstName = firstName; >>> } >>> private java.lang.String lastName; >>> public java.lang.String getLastName() { >>> return this.lastName; >>> } >>> public void setLastName(java.lang.String lastName) { >>> this.lastName = lastName; >>> } >>> ------------ Entity class (END) ------------------------------ >>> ------------ persistence.xml (START) ------------------------------ >>> <?xml version="1.0" encoding="UTF-8"?> <persistence >>> xmlns="http://java.sun.com/xml/ns/persistence" >>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"> >>> <persistence-unit name="example" >>> transaction-type="RESOURCE_LOCAL"> >>> >>> >>> > <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provid > er> >>> <!-- We must enumerate each entity in the persistence unit > --> >>> <class>example.Consumer</class> >>> <properties> >>> <property name="openjpa.jdbc.DBDictionary" > value="postgres"/> >>> <property name="openjpa.ConnectionDriverName" >>> value="org.postgresql.Driver"/> >>> <property name="openjpa.ConnectionUserName" >>> value="app_user"/> >>> <property name="openjpa.ConnectionPassword" >>> value="app_user"/> >>> <property name="openjpa.ConnectionURL" >>> value="jdbc:postgresql://localhost/alikic"/> >>> <property name="openjpa.Log" >>> value="DefaultLevel=WARN,SQL=TRACE"/> >>> >>> </properties> >>> </persistence-unit> >>> >>> </persistence> >>> ------------ persistence.xml (END) ------------------------------ >>> ------------ orm.xml (START) ------------------------------ >>> <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" >>> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >>> xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm >>> orm_1_0.xsd" >>> version="1.0"> >>> <entity class="example.Consumer"> >>> <attributes> >>> <id name="id"> >>> <generated-value strategy="IDENTITY"/> >>> </id> >>> <basic name="firstName"> >>> <column name="first_name"/> >>> </basic> >>> <basic name="lastName"> >>> <column name="last_name"/> >>> </basic> >>> </attributes> >>> </entity> >>> </entity-mappings> >>> ------------ orm.xml (END) ------------------------------ >> >> -- >> This message is automatically generated by JIRA. >> - >> You can reply to this email to add a comment to the issue online. >> >> >> > > -- > View this message in context: > http://www.nabble.com/-jira--Created%3A-%28OPENJPA-245%29-Attach-NEW-and > -auto-increment-identity-tf3823771.html#a10860565 > Sent from the open-jpa-dev mailing list archive at Nabble.com. > > > Notice: This email message, together with any attachments, may contain > information of BEA Systems, Inc., its subsidiaries and affiliated > entities, that may be confidential, proprietary, copyrighted and/or > legally privileged, and is intended solely for the use of the individual > or entity named in this message. If you are not the intended recipient, > and have received this message in error, please immediately return this by > email and then delete it. > > -- View this message in context: http://www.nabble.com/-jira--Created%3A-%28OPENJPA-245%29-Attach-NEW-and-auto-increment-identity-tf3823771.html#a10873421 Sent from the open-jpa-dev mailing list archive at Nabble.com.