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.

Reply via email to