You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by "Fay Wang (JIRA)" <ji...@apache.org> on 2009/10/30 23:51:59 UTC

[jira] Created: (OPENJPA-1371) Insert is called instead of Update when merge() with derived Identity

Insert is called instead of Update when merge() with derived Identity
---------------------------------------------------------------------

                 Key: OPENJPA-1371
                 URL: https://issues.apache.org/jira/browse/OPENJPA-1371
             Project: OpenJPA
          Issue Type: Bug
          Components: kernel
    Affects Versions: 2.0.0-M3
            Reporter: Fay Wang
             Fix For: 2.0.0-M3


Insert is called instead of Update when merge() with derived Identity:

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (OPENJPA-1371) Insert is called instead of Update when merge() with derived Identity

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

Donald Woods resolved OPENJPA-1371.
-----------------------------------

       Resolution: Fixed
    Fix Version/s:     (was: 2.0.0)
                   2.0.0-M3

> Insert is called instead of Update when merge() with derived Identity
> ---------------------------------------------------------------------
>
>                 Key: OPENJPA-1371
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1371
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.0.0-M3
>            Reporter: Fay Wang
>             Fix For: 2.0.0-M3
>
>
> Insert is called instead of Update when merge() with derived Identity:

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (OPENJPA-1371) Insert is called instead of Update when merge() with derived Identity

Posted by "Fay Wang (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/OPENJPA-1371?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12772296#action_12772296 ] 

Fay Wang commented on OPENJPA-1371:
-----------------------------------

During merge, openjpa needs to retrieve id from the entity to decide whether this is a new entity or a detached one. If it thinks it is a new entity, an INSERT will be perform. Otherwise, an Update statement will be executed. 
If  (1) an entity has the compound primary key using IdClass, and 
    (2) some field in the IdClass is a derived identity from a OneToOne/ManyToOne field,
    (3) that value in that field has not yet become managed (i.e., does not have the StateManagerImpl yet),
this field in the IdClass will not be populated, as the primary key of the OneToOne/ManyToOne field usually can not be fetched back without an associated StateManagerImpl, unless it has a single-value primary key. 

Currently openjpa returns the null value for this field in the IdClass regardlessly in the above situation.  The patch provides a relief when this derived identity-relation field has a single value primary key. It should fix the problem reported by Constantine. However, the limitation for nested/multi-level compound primary (e.g. Stock entity has compound primary key using IdClass, and some value in the idClass is a derived-identity relation field, ...) during merge remains.   


> Insert is called instead of Update when merge() with derived Identity
> ---------------------------------------------------------------------
>
>                 Key: OPENJPA-1371
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1371
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.0.0-M3
>            Reporter: Fay Wang
>             Fix For: 2.0.0-M3
>
>
> Insert is called instead of Update when merge() with derived Identity:

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (OPENJPA-1371) Insert is called instead of Update when merge() with derived Identity

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

Donald Woods updated OPENJPA-1371:
----------------------------------

    Fix Version/s:     (was: 2.0.0-M3)
                   2.0.0

> Insert is called instead of Update when merge() with derived Identity
> ---------------------------------------------------------------------
>
>                 Key: OPENJPA-1371
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1371
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.0.0-M3
>            Reporter: Fay Wang
>             Fix For: 2.0.0
>
>
> Insert is called instead of Update when merge() with derived Identity:

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (OPENJPA-1371) Insert is called instead of Update when merge() with derived Identity

Posted by "Fay Wang (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/OPENJPA-1371?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12772179#action_12772179 ] 

Fay Wang commented on OPENJPA-1371:
-----------------------------------

The following test scenario is provided by Constantine Kulak <co...@mail.by>:

There are three entities where PrognosisEntry has derived identity:

***** Source for Prognosis.java:

 @Entity(name = "Prognosis")
 @Table(name = "PROGNOSIS")
 @IdClass(Prognosis.PrognosisId.class)
 @Inheritance(strategy = InheritanceType.JOINED)
 public class Prognosis {

     protected List<PrognosisEntry> entries;
    protected String station;
    protected String type;

    @OneToMany(targetEntity = PrognosisEntry.class, cascade = {CascadeType.MERGE}, mappedBy="prognosis", fetch=FetchType.EAGER)
    public List<PrognosisEntry> getEntries() {
        if (entries == null) {
            entries = new ArrayList<PrognosisEntry>();
        }
        return this.entries;
    }

    public void setEntries(List<PrognosisEntry> entries) {
        this.entries = entries;
    }

    @Id
    @Column(name = "STATION")
    public String getStation() {
        return station;
    }

    public void setStation(String value) {
        this.station = value;
    }

    @Id
    @Column(name = "TYPE_")
    public String getType() {
        return type;
    }

    public void setType(String value) {
        this.type = value;
    }

    public boolean equals(Object object) { ... }
    public int hashCode() { ... }

    public static class PrognosisId {
        protected String station;
        protected String type;

        public String getStation() {
            return station;
        }

        public void setStation(String value) {
            this.station = value;
        }

        public String getType() {
            return type;
        }

        public void setType(String value) {
            this.type = value;
        }

          public boolean equals(Object object) { ... }
        public int hashCode() { ... }
    }
 }


 ***** Source for PrognosisEntry.java:

 @Entity(name = "PrognosisEntry")
 @Table(name = "PROGNOSISENTRY")
 @Inheritance(strategy = InheritanceType.JOINED)
 @IdClass(PrognosisEntry.PrognosisEntryId.class)
 public class PrognosisEntry {

    protected String timestamp;
    protected String localState;
    protected Prognosis prognosis;

    protected Stock stock;

    @Id
    @ManyToOne(targetEntity = Stock.class, cascade = { CascadeType.MERGE }, fetch = FetchType.EAGER)
    public Stock getStock() {
        return stock;
    }

    public void setStock(Stock stock) {
        this.stock = stock;
    }

    @Id
    @ManyToOne(targetEntity = Prognosis.class, cascade = { CascadeType.MERGE }, fetch = FetchType.EAGER)
    public Prognosis getPrognosis() {
        return prognosis;
    }

    public void setPrognosis(Prognosis prognosis) {
        this.prognosis = prognosis;
    }

    @Column(name = "TIMESTAMP_", length = 255)
    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String value) {
        this.timestamp = value;
    }

    @Basic
    @Column(name = "LOCALSTATE", length = 255)
    public String getLocalState() {
        return localState;
    }

    public void setLocalState(String value) {
        this.localState = value;
    }

    public boolean equals(Object object) { ... }
    public int hashCode() { ... }

    public static class PrognosisEntryId {

        protected Prognosis.PrognosisId prognosis;
        protected String stock;

        public String getStock() {
            return stock;
        }

        public void setStock(String stock) {
            this.stock = stock;
        }

        public Prognosis.PrognosisId getPrognosis() {
            return prognosis;
        }

        public void setPrognosis(Prognosis.PrognosisId prognosis) {
            this.prognosis = prognosis;
        }

        public boolean equals(Object object) { ... }
        public int hashCode() { ... }
    }
 }


 ***** Source for Stock.java:

 @Entity(name = "Stock")
 @Table(name = "STOCK")
 @Inheritance(strategy = InheritanceType.JOINED)
 public class Stock {
    protected String index;
    protected String length;

    @Id
    @Column(name = "INDEX_")
    public String getIndex() {
        return index;
    }

    public void setIndex(String value) {
        this.index = value;
    }
      @Basic
    @Column(name = "LENGTH_", length = 255)
    public String getLength() {
        return length;
    }

    public void setLength(String value) {
        this.length = value;
    }

    public boolean equals(Object object) { ... }
    public int hashCode() { ... }
}

The test scenario: 
(1) create a Prognosis entity with a list of PrognosisEntry.
(2) call em.merge(newEntity) and commit
(3) call em.clear()
(4) call em.merge(newEntity)

Step (4) generate insert statement to insert PrognosisEntry again, resulting in unique constraint violation from the database.

It appears that the ApplicationIds.create(pc, meta) where pc is PrognosisEntry, the oid does not have complete id values.











> Insert is called instead of Update when merge() with derived Identity
> ---------------------------------------------------------------------
>
>                 Key: OPENJPA-1371
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1371
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.0.0-M3
>            Reporter: Fay Wang
>             Fix For: 2.0.0-M3
>
>
> Insert is called instead of Update when merge() with derived Identity:

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.