You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by "Aleksandar Likic (JIRA)" <ji...@apache.org> on 2007/05/27 16:05:16 UTC

[jira] Created: (OPENJPA-245) Attach NEW and auto-increment identity

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.7, 0.9.6
         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</provider>

        <!-- 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.


RE: [jira] Created: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by Aleksandar Likic <al...@rogers.com>.
The entity is using auto-generated identity - please see the attached
orm.xml.

            <id name="id">
                <generated-value strategy="IDENTITY"/>
            </id>

I am creating NEW instance and assigning an already existing primary key
only to reproduce the problem. The real-life scenario is that a web service
performs de-serialization of input XML parameter and, in the process,
creates a new instance of an entity that has a primary key that already
exists in database (this is done by server-side code generated using WL jwsc
ant task from WL 9.2.1). em.merge() apparently doesn't work correctly in
this case, since a new record is created in database on commit.

Regards,
Aleksandar Likic


Pinaki Poddar wrote:
> 
>>> just create a new instance of an entity, assign an already existing
> primary key
>>> A new record will be created in database, with new, auto-generated
> primary key.
> 
> What is the identity mechanicsm used by the entity class? 
> If the entity is using auto-generated identity then assigning an
> "already existing" key is not recommneded. 
> If the entity is not using auto-generated, then assigning an existing
> key *should* fail at commit with duplicate key exception.  
> 
> 
> Pinaki Poddar
> BEA Systems
> 415.402.7317  
> 
> 
> -----Original Message-----
> From: Aleksandar Likic (JIRA) [mailto:jira@apache.org] 
> Sent: Sunday, May 27, 2007 9:05 AM
> To: open-jpa-dev@incubator.apache.org
> Subject: [jira] Created: (OPENJPA-245) Attach NEW and auto-increment
> identity
> 
> 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.7, 0.9.6
>          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.
> 
> 
> 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#a10854791
Sent from the open-jpa-dev mailing list archive at Nabble.com.


RE: [jira] Created: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by Pinaki Poddar <pp...@bea.com>.
>> just create a new instance of an entity, assign an already existing
primary key
>> A new record will be created in database, with new, auto-generated
primary key.

What is the identity mechanicsm used by the entity class? 
If the entity is using auto-generated identity then assigning an
"already existing" key is not recommneded. 
If the entity is not using auto-generated, then assigning an existing
key *should* fail at commit with duplicate key exception.  


Pinaki Poddar
BEA Systems
415.402.7317  


-----Original Message-----
From: Aleksandar Likic (JIRA) [mailto:jira@apache.org] 
Sent: Sunday, May 27, 2007 9:05 AM
To: open-jpa-dev@incubator.apache.org
Subject: [jira] Created: (OPENJPA-245) Attach NEW and auto-increment
identity

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.7, 0.9.6
         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.


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.

RE: [jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by Pinaki Poddar <pp...@bea.com>.
 > * 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.

I could get OpenJPA to behave in this way (i.e. without a version or
detachment) only when the entity class was annotated with 
@DetachedState(enabled=false)  




Pinaki Poddar
BEA Systems
415.402.7317  


-----Original Message-----
From: Aleksandar Likic [mailto:alikic@rogers.com] 
Sent: Wednesday, May 30, 2007 8:21 AM
To: open-jpa-dev@incubator.apache.org
Subject: RE: [jira] Commented: (OPENJPA-245) Attach NEW and
auto-increment identity


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:alikic@rogers.com]
> 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 jira@apache.org 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</prov
> id
> 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-a
> nd
> -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.


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.

RE: [jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by Aleksandar Likic <al...@rogers.com>.
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:alikic@rogers.com] 
> 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 jira@apache.org 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.


RE: [jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by Pinaki Poddar <pp...@bea.com>.
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:alikic@rogers.com] 
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 jira@apache.org 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.

Re: [jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by Aleksandar Likic <al...@rogers.com>.
>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 jira@apache.org wrote:
> 
> 
>     [
> https://issues.apache.org/jira/browse/OPENJPA-245?page=com.atlassian.jira.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</provider>
>>         <!-- 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.


Re: [jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by Aleksandar Likic <al...@rogers.com>.
Sounds good. You just need to update the documentation to clarify this. To
me, the annotation @DetachedState(enabled=false) looks like a sensible
default which one wouldn't need to specify explicitly. If it has to be
specified explicitly in order to achieve this behavior, this fact has to be
documented.

Thanks for you help,
Aleksandar Likic


JIRA jira@apache.org wrote:
> 
> 
>     [
> https://issues.apache.org/jira/browse/OPENJPA-245?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12500235
> ] 
> 
> Pinaki Poddar commented on OPENJPA-245:
> ---------------------------------------
> 
> An entity instance x which has been created by new() operator and carrying
> a existing id (say idx) set by the user application is treated as detached
> by merge() when the entity class is annotated with
> @DetachState(enabled=false). Then merge() updates the existing database
> record with current state of x. If it is not annotated with
> @DetachState(enabled=false), the instance x is trated as a new instance,
> and if the entity is using auto-generated identity, a new database record
> is created, ignoring the id set by the application. However, if the
> entitymanager doing the merge() is already managing an instance with the
> same identity idx then an EntityExists exception is raised. 
> 
> The generated enhanced code differs based on @DetachedState setting. 
> So if the application has changed this setting, the entity must be
> enhanced again.   
> 
> 
> 
> 
>> 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
>>         Attachments: TestMerge.zip
>>
>>
>> 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</provider>
>>         <!-- 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#a10894279
Sent from the open-jpa-dev mailing list archive at Nabble.com.


[jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by "Pinaki Poddar (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/OPENJPA-245?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12499951 ] 

Pinaki Poddar commented on OPENJPA-245:
---------------------------------------

>From openjpa documentation (ref: 1.2.  Attach Behavior)

"  * 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.
   * 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."

The implementaion does not seem to adhere to the last statement above. This is observed by the original scenario described in this issue as well as the attached testcase testMergeUnversionedNewObjectCreatesNewRecord(). 

AttachStrategy implementaion is responsible for merge().  For a newly created entity instance even if it carries id of a persistent record -- the  attach strategy selected (by AttachManager.getStrategy() method) is VersionAttachStrategy. Now, VersionAttachStrategy determines whether the instance to be attached is new by the following logic:

boolean isNew = !broker.isDetached(pc); // VersionAttachStrategy.java:70

which turns out to be true in this case. 

With the current implementation, VersionAttachStrategy does not detect that a) the instance to be attached is carrying a primary key equal to a pre-existing data record and b) hence it should be an update and not an insert. However, it passes the instance as PNEW further downstream to be flushed (the instance is still carrying a primary key value same as the one set by the application and a record with the same key exists). However, as the identity field is annotated with GenerateValue.IDENTITY -- the PNEW instance gets stored without a duplicate key exception and its primary key in the database is auto incremented. That the primary key value assigned by the user application is ignored and a new value is assigned can also be verified (see the testcase).     

This is the flow for a new instance being merged in a context which is not managing another instance with the same primary key. If the new instance carrying an existing key was merged to a EntityManager that already is managing another instance, because the attach strategy still considered the to be merged instance as PNEW -- a EntityExistsException is raised by the object management kernel even before attampting a flush to the database.

> 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
>         Attachments: TestMerge.zip
>
>
> 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</provider>
>         <!-- 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.


[jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by "Pinaki Poddar (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/OPENJPA-245?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12500235 ] 

Pinaki Poddar commented on OPENJPA-245:
---------------------------------------

An entity instance x which has been created by new() operator and carrying a existing id (say idx) set by the user application is treated as detached by merge() when the entity class is annotated with @DetachState(enabled=false). Then merge() updates the existing database record with current state of x. If it is not annotated with @DetachState(enabled=false), the instance x is trated as a new instance, and if the entity is using auto-generated identity, a new database record is created, ignoring the id set by the application. However, if the entitymanager doing the merge() is already managing an instance with the same identity idx then an EntityExists exception is raised. 

The generated enhanced code differs based on @DetachedState setting. 
So if the application has changed this setting, the entity must be enhanced again.   




> 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
>         Attachments: TestMerge.zip
>
>
> 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</provider>
>         <!-- 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.


[jira] Commented: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by "Pinaki Poddar (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/OPENJPA-245?page=com.atlassian.jira.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</provider>
>         <!-- 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.


[jira] Updated: (OPENJPA-245) Attach NEW and auto-increment identity

Posted by "Pinaki Poddar (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/OPENJPA-245?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Pinaki Poddar updated OPENJPA-245:
----------------------------------

    Attachment: TestMerge.zip

Attached a test case that demonstates merge() behaviour of entities with or without a version field and when the merged instance is a clone or a copy. A clone is created by serialization+deserialization of the original persistent instance. A copy is created by Java new() operator and then fields values are set equal to the original persistent instance (including the primary key field). 

Thus we have four scenarios:
1. Unversioned + Copy
2. Unversioned + Clone
3. Versioned + Copy
4. Versioned + Clone

The  first case originated this issue (at least that's what I gathered from the description). The first case behaves 'rationally but non-intutively'. It creates a new database record rather than updating the existing one. The merge() operation does not see a versioned field, treats the argument instance as a new instance, assigns a new identity (ignoring what the application has set).
If the entity were using application identity, one would have encountered a DuplicateKeyException of some sort, I presume but not tested here.

The rest three cases update the existing record. In the third case, the user application has to copy the version field for merge() to treat the merged instance 'correctly' i.e. as a update rather than an insert of a new record. This seems to be the solution to the original use cse -- add a version field and copy the version field to the merged instance.      
 

> 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
>         Attachments: TestMerge.zip
>
>
> 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</provider>
>         <!-- 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.