You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Constantine Kulak <co...@mail.by> on 2009/10/29 12:19:11 UTC

Insert is called instead of Update when merge() with complex IDs

Hello!

I need some help in the following situation - completely stuck with it :(
Can you please point me in some direction? Anyway, thanks in advance!
OpenJPA version is 2.0.0-M3.

So, I have three entities:

Prognosis contains many PrognosisEntry, and PrognosisEntry references 
some Stock. So, it's a many-to-many for Prognosis and Stock, having some 
additional data at PrognosisEntry join table. Fields:

Stock:
    index (PK)
    length

Prognosis:
    station (PK)
    type (PK)

PrognosisEntry:
    prognosis.station (FK, PK)
    prognosis.type (FK, PK)
    stock.index (FK, PK)
    localState
    timestamp

Relationship between Prognosis and PrognosisEntry is bidirectional (I 
really need Prognosis.getEntries() method). All IDs are taken from the 
real world and not generated because this data comes from the backend in 
XML and then deserialized using JAXB (annotations are removed from the 
sources below to simplify it). Then I do merge() and expect the data in 
the DB to be updated with the fresh one. When I call merge() for the 1st 
time (against the empty DB), all the necessary INSERTs are done. But 
when called for the 2nd time with the same data (I expect no changes to 
the DB), the exception is thrown because of the duplicate primary keys. 
Unexpectedly, it does INSERT instead of UPDATE in this case. The problem 
is seems to be with the PrognosisEntry-Stock relationship, because when 
I remove it (replacing reference to Stock in the PrognosisEntry with 
some dummy ID field) it starts working as expected (calls UPDATE). 
Exception and logs are given after the sources below.

***** 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() { ... }
}


***** Generated DDL:

CREATE TABLE PROGNOSIS (STATION VARCHAR(254) NOT NULL, TYPE_ 
VARCHAR(254) NOT NULL, PRIMARY KEY (STATION, TYPE_));
CREATE TABLE PROGNOSISENTRY (PROGNOSIS_STATION VARCHAR(254) NOT NULL, 
PROGNOSIS_TYPE_ VARCHAR(254) NOT NULL, STOCK_INDEX_ VARCHAR(254) NOT 
NULL, LOCALSTATE VARCHAR(254), TIMESTAMP_ VARCHAR(254), PRIMARY KEY 
(PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_));
CREATE TABLE STOCK (INDEX_ VARCHAR(254) NOT NULL, LENGTH_ VARCHAR(254), 
WEIGHT VARCHAR(254), PRIMARY KEY (INDEX_));
ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (PROGNOSIS_STATION, 
PROGNOSIS_TYPE_) REFERENCES PROGNOSIS (STATION, TYPE_);
ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (STOCK_INDEX_) REFERENCES 
STOCK (INDEX_);


***** Executed SQL and exception:

3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> 
executing prepstmnt 379983526 SELECT t0.STATION, t0.TYPE_ FROM PROGNOSIS 
t0 WHERE t0.STATION = ? AND t0.TYPE_ = ?  [params=(String) 1400, 
(String) IN]
3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> 
[0 ms] spent
3078  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1004551136> 
[0 ms] close
3125  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> 
executing prepstmnt 1663984430 SELECT t0.PROGNOSIS_STATION, 
t0.PROGNOSIS_TYPE_, t0.STOCK_INDEX_, t0.LOCALSTATE, t1.INDEX_, 
t1.LENGTH_, t1.WEIGHT, t0.TIMESTAMP_ FROM PROGNOSISENTRY t0 LEFT OUTER 
JOIN STOCK t1 ON t0.STOCK_INDEX_ = t1.INDEX_ WHERE t0.PROGNOSIS_STATION 
= ? AND t0.PROGNOSIS_TYPE_ = ?  [params=(String) 1400, (String) IN]
3156  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> 
[31 ms] spent
3156  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1901752666> 
[0 ms] close
3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> 
executing prepstmnt 140118106 SELECT t0.LOCALSTATE, t1.STATION, 
t1.TYPE_, t2.INDEX_, t2.LENGTH_, t2.WEIGHT, t0.TIMESTAMP_ FROM 
PROGNOSISENTRY t0 LEFT OUTER JOIN PROGNOSIS t1 ON t0.PROGNOSIS_STATION = 
t1.STATION AND t0.PROGNOSIS_TYPE_ = t1.TYPE_ LEFT OUTER JOIN STOCK t2 ON 
t0.STOCK_INDEX_ = t2.INDEX_ WHERE t0.PROGNOSIS_STATION = ? AND 
t0.PROGNOSIS_TYPE_ = ? AND t0.STOCK_INDEX_ IS NULL  optimize for 1 row 
[params=(String) 1400, (String) IN]
3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> 
[0 ms] spent
3219  WARN   [main] openjpa.Runtime - Finder for "PrognosisEntry" is not 
cachable.
3219  TRACE  [main] openjpa.Runtime - finder-invalidate
3219  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1242843668> 
[0 ms] close
3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> 
executing prepstmnt 317330154 SELECT t0.LENGTH_, t0.WEIGHT FROM STOCK t0 
WHERE t0.INDEX_ = ?  [params=(String) 3]
3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> [0 
ms] spent
3281  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 391649112> 
[0 ms] close
3344  TRACE  [main] openjpa.jdbc.JDBC - The batch limit is set to 100.
3344  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> 
executing prepstmnt 686827760 INSERT INTO PROGNOSISENTRY 
(PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, 
TIMESTAMP_) VALUES (?, ?, ?, ?, ?) [params=(String) 1400, (String) IN, 
(String) 3, (null) null, (String) 2009-12-09-17.34]
3547  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> 
[171 ms] spent

<openjpa-2.0.0-M3-r422266:822833 fatal store error> 
org.apache.openjpa.util.StoreException: The transaction has been rolled 
back.  See the nested exceptions for details on the errors that occurred.
    at 
org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2249)
    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2096)
    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1994)
    at 
org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1912)
    at 
org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
    at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1436)
    at 
org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:895)
    at 
org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:557)
    at test.persistParent(test.java:34)
    at test.main(test.java:16)
Caused by: <openjpa-2.0.0-M3-r422266:822833 fatal store error> 
org.apache.openjpa.util.ObjectExistsException: One or more values in the 
INSERT statement, UPDATE statement, or foreign key update caused by a 
DELETE statement are not valid because the primary key, unique 
constraint or unique index identified by "1" constrains table 
"PROGNOSISENTRY" from having duplicate values for the index key.
FailedObject: prepstmnt 686827760 INSERT INTO PROGNOSISENTRY 
(PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, 
TIMESTAMP_) VALUES (?, ?, ?, ?, ?) 
[org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement_]
    at 
org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4575)
    at 
org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4543)
    at 
org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:541)
...

--
Constantine Kulak
wintermuteblog.blogspot.com


Re: Insert is called instead of Update when merge() with complex IDs

Posted by Fay Wang <fy...@yahoo.com>.
This is a bug in openjpa. JIRA-1371 is open to address this problem.



----- Original Message ----
From: Constantine Kulak <co...@mail.by>
To: users@openjpa.apache.org
Sent: Fri, October 30, 2009 12:54:19 AM
Subject: Re: Insert is called instead of Update when merge() with complex IDs

Hello!

Neither of those, I just execute the program twice. So, it's not about 
the managed / detached entities.

Fay Wang wrote:
> The em.merge will return the merged entity. 
>
>     EntityA mergedEntity = em.merge(newEntity);
>
> During your second merge call, did you call 
>    em.merge(mergedEntity)
> or 
>   em.merge(newEntity)?
>
> Fay
>
>
>
> ----- Original Message ----
> From: Constantine Kulak <co...@mail.by>
> To: users@openjpa.apache.org
> Sent: Thu, October 29, 2009 4:19:11 AM
> Subject: Insert is called instead of Update when merge() with complex IDs
>
> Hello!
>
> I need some help in the following situation - completely stuck with it :(
> Can you please point me in some direction? Anyway, thanks in advance!
> OpenJPA version is 2.0.0-M3.
>
> So, I have three entities:
>
> Prognosis contains many PrognosisEntry, and PrognosisEntry references some Stock. So, it's a many-to-many for Prognosis and Stock, having some additional data at PrognosisEntry join table. Fields:
>
> Stock:
>    index (PK)
>    length
>
> Prognosis:
>    station (PK)
>    type (PK)
>
> PrognosisEntry:
>    prognosis.station (FK, PK)
>    prognosis.type (FK, PK)
>    stock.index (FK, PK)
>    localState
>    timestamp
>
> Relationship between Prognosis and PrognosisEntry is bidirectional (I really need Prognosis.getEntries() method). All IDs are taken from the real world and not generated because this data comes from the backend in XML and then deserialized using JAXB (annotations are removed from the sources below to simplify it). Then I do merge() and expect the data in the DB to be updated with the fresh one. When I call merge() for the 1st time (against the empty DB), all the necessary INSERTs are done. But when called for the 2nd time with the same data (I expect no changes to the DB), the exception is thrown because of the duplicate primary keys. Unexpectedly, it does INSERT instead of UPDATE in this case. The problem is seems to be with the PrognosisEntry-Stock relationship, because when I remove it (replacing reference to Stock in the PrognosisEntry with some dummy ID field) it starts working as expected (calls UPDATE). Exception and logs are given after the
>  sources below.
>
> ***** 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() { ... }
> }
>
>
> ***** Generated DDL:
>
> CREATE TABLE PROGNOSIS (STATION VARCHAR(254) NOT NULL, TYPE_ VARCHAR(254) NOT NULL, PRIMARY KEY (STATION, TYPE_));
> CREATE TABLE PROGNOSISENTRY (PROGNOSIS_STATION VARCHAR(254) NOT NULL, PROGNOSIS_TYPE_ VARCHAR(254) NOT NULL, STOCK_INDEX_ VARCHAR(254) NOT NULL, LOCALSTATE VARCHAR(254), TIMESTAMP_ VARCHAR(254), PRIMARY KEY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_));
> CREATE TABLE STOCK (INDEX_ VARCHAR(254) NOT NULL, LENGTH_ VARCHAR(254), WEIGHT VARCHAR(254), PRIMARY KEY (INDEX_));
> ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (PROGNOSIS_STATION, PROGNOSIS_TYPE_) REFERENCES PROGNOSIS (STATION, TYPE_);
> ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (STOCK_INDEX_) REFERENCES STOCK (INDEX_);
>
>
> ***** Executed SQL and exception:
>
> 3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> executing prepstmnt 379983526 SELECT t0.STATION, t0.TYPE_ FROM PROGNOSIS t0 WHERE t0.STATION = ? AND t0.TYPE_ = ?  [params=(String) 1400, (String) IN]
> 3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> [0 ms] spent
> 3078  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1004551136> [0 ms] close
> 3125  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> executing prepstmnt 1663984430 SELECT t0.PROGNOSIS_STATION, t0.PROGNOSIS_TYPE_, t0.STOCK_INDEX_, t0.LOCALSTATE, t1.INDEX_, t1.LENGTH_, t1.WEIGHT, t0.TIMESTAMP_ FROM PROGNOSISENTRY t0 LEFT OUTER JOIN STOCK t1 ON t0.STOCK_INDEX_ = t1.INDEX_ WHERE t0.PROGNOSIS_STATION = ? AND t0.PROGNOSIS_TYPE_ = ?  [params=(String) 1400, (String) IN]
> 3156  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> [31 ms] spent
> 3156  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1901752666> [0 ms] close
> 3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> executing prepstmnt 140118106 SELECT t0.LOCALSTATE, t1.STATION, t1.TYPE_, t2.INDEX_, t2.LENGTH_, t2.WEIGHT, t0.TIMESTAMP_ FROM PROGNOSISENTRY t0 LEFT OUTER JOIN PROGNOSIS t1 ON t0.PROGNOSIS_STATION = t1.STATION AND t0.PROGNOSIS_TYPE_ = t1.TYPE_ LEFT OUTER JOIN STOCK t2 ON t0.STOCK_INDEX_ = t2.INDEX_ WHERE t0.PROGNOSIS_STATION = ? AND t0.PROGNOSIS_TYPE_ = ? AND t0.STOCK_INDEX_ IS NULL  optimize for 1 row [params=(String) 1400, (String) IN]
> 3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> [0 ms] spent
> 3219  WARN   [main] openjpa.Runtime - Finder for "PrognosisEntry" is not cachable.
> 3219  TRACE  [main] openjpa.Runtime - finder-invalidate
> 3219  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1242843668> [0 ms] close
> 3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> executing prepstmnt 317330154 SELECT t0.LENGTH_, t0.WEIGHT FROM STOCK t0 WHERE t0.INDEX_ = ?  [params=(String) 3]
> 3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> [0 ms] spent
> 3281  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 391649112> [0 ms] close
> 3344  TRACE  [main] openjpa.jdbc.JDBC - The batch limit is set to 100.
> 3344  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> executing prepstmnt 686827760 INSERT INTO PROGNOSISENTRY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, TIMESTAMP_) VALUES (?, ?, ?, ?, ?) [params=(String) 1400, (String) IN, (String) 3, (null) null, (String) 2009-12-09-17.34]
> 3547  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> [171 ms] spent
>
> <openjpa-2.0.0-M3-r422266:822833 fatal store error> org.apache.openjpa.util.StoreException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
>    at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2249)
>    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2096)
>    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1994)
>    at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1912)
>    at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
>    at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1436)
>    at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:895)
>    at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:557)
>    at test.persistParent(test.java:34)
>    at test.main(test.java:16)
> Caused by: <openjpa-2.0.0-M3-r422266:822833 fatal store error> org.apache.openjpa.util.ObjectExistsException: One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "1" constrains table "PROGNOSISENTRY" from having duplicate values for the index key.
> FailedObject: prepstmnt 686827760 INSERT INTO PROGNOSISENTRY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, TIMESTAMP_) VALUES (?, ?, ?, ?, ?) [org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement_]
>    at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4575)
>    at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4543)
>    at org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:541)
> ...

--
Constantine Kulak
wintermuteblog.blogspot.com


      

Re: Insert is called instead of Update when merge() with complex IDs

Posted by Constantine Kulak <co...@mail.by>.
Hello!

Neither of those, I just execute the program twice. So, it's not about 
the managed / detached entities.

Fay Wang wrote:
> The em.merge will return the merged entity. 
>
>     EntityA mergedEntity = em.merge(newEntity);
>
> During your second merge call, did you call 
>    em.merge(mergedEntity)
> or 
>   em.merge(newEntity)?
>
> Fay
>
>
>
> ----- Original Message ----
> From: Constantine Kulak <co...@mail.by>
> To: users@openjpa.apache.org
> Sent: Thu, October 29, 2009 4:19:11 AM
> Subject: Insert is called instead of Update when merge() with complex IDs
>
> Hello!
>
> I need some help in the following situation - completely stuck with it :(
> Can you please point me in some direction? Anyway, thanks in advance!
> OpenJPA version is 2.0.0-M3.
>
> So, I have three entities:
>
> Prognosis contains many PrognosisEntry, and PrognosisEntry references some Stock. So, it's a many-to-many for Prognosis and Stock, having some additional data at PrognosisEntry join table. Fields:
>
> Stock:
>    index (PK)
>    length
>
> Prognosis:
>    station (PK)
>    type (PK)
>
> PrognosisEntry:
>    prognosis.station (FK, PK)
>    prognosis.type (FK, PK)
>    stock.index (FK, PK)
>    localState
>    timestamp
>
> Relationship between Prognosis and PrognosisEntry is bidirectional (I really need Prognosis.getEntries() method). All IDs are taken from the real world and not generated because this data comes from the backend in XML and then deserialized using JAXB (annotations are removed from the sources below to simplify it). Then I do merge() and expect the data in the DB to be updated with the fresh one. When I call merge() for the 1st time (against the empty DB), all the necessary INSERTs are done. But when called for the 2nd time with the same data (I expect no changes to the DB), the exception is thrown because of the duplicate primary keys. Unexpectedly, it does INSERT instead of UPDATE in this case. The problem is seems to be with the PrognosisEntry-Stock relationship, because when I remove it (replacing reference to Stock in the PrognosisEntry with some dummy ID field) it starts working as expected (calls UPDATE). Exception and logs are given after the
>  sources below.
>
> ***** 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() { ... }
> }
>
>
> ***** Generated DDL:
>
> CREATE TABLE PROGNOSIS (STATION VARCHAR(254) NOT NULL, TYPE_ VARCHAR(254) NOT NULL, PRIMARY KEY (STATION, TYPE_));
> CREATE TABLE PROGNOSISENTRY (PROGNOSIS_STATION VARCHAR(254) NOT NULL, PROGNOSIS_TYPE_ VARCHAR(254) NOT NULL, STOCK_INDEX_ VARCHAR(254) NOT NULL, LOCALSTATE VARCHAR(254), TIMESTAMP_ VARCHAR(254), PRIMARY KEY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_));
> CREATE TABLE STOCK (INDEX_ VARCHAR(254) NOT NULL, LENGTH_ VARCHAR(254), WEIGHT VARCHAR(254), PRIMARY KEY (INDEX_));
> ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (PROGNOSIS_STATION, PROGNOSIS_TYPE_) REFERENCES PROGNOSIS (STATION, TYPE_);
> ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (STOCK_INDEX_) REFERENCES STOCK (INDEX_);
>
>
> ***** Executed SQL and exception:
>
> 3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> executing prepstmnt 379983526 SELECT t0.STATION, t0.TYPE_ FROM PROGNOSIS t0 WHERE t0.STATION = ? AND t0.TYPE_ = ?  [params=(String) 1400, (String) IN]
> 3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> [0 ms] spent
> 3078  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1004551136> [0 ms] close
> 3125  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> executing prepstmnt 1663984430 SELECT t0.PROGNOSIS_STATION, t0.PROGNOSIS_TYPE_, t0.STOCK_INDEX_, t0.LOCALSTATE, t1.INDEX_, t1.LENGTH_, t1.WEIGHT, t0.TIMESTAMP_ FROM PROGNOSISENTRY t0 LEFT OUTER JOIN STOCK t1 ON t0.STOCK_INDEX_ = t1.INDEX_ WHERE t0.PROGNOSIS_STATION = ? AND t0.PROGNOSIS_TYPE_ = ?  [params=(String) 1400, (String) IN]
> 3156  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> [31 ms] spent
> 3156  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1901752666> [0 ms] close
> 3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> executing prepstmnt 140118106 SELECT t0.LOCALSTATE, t1.STATION, t1.TYPE_, t2.INDEX_, t2.LENGTH_, t2.WEIGHT, t0.TIMESTAMP_ FROM PROGNOSISENTRY t0 LEFT OUTER JOIN PROGNOSIS t1 ON t0.PROGNOSIS_STATION = t1.STATION AND t0.PROGNOSIS_TYPE_ = t1.TYPE_ LEFT OUTER JOIN STOCK t2 ON t0.STOCK_INDEX_ = t2.INDEX_ WHERE t0.PROGNOSIS_STATION = ? AND t0.PROGNOSIS_TYPE_ = ? AND t0.STOCK_INDEX_ IS NULL  optimize for 1 row [params=(String) 1400, (String) IN]
> 3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> [0 ms] spent
> 3219  WARN   [main] openjpa.Runtime - Finder for "PrognosisEntry" is not cachable.
> 3219  TRACE  [main] openjpa.Runtime - finder-invalidate
> 3219  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1242843668> [0 ms] close
> 3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> executing prepstmnt 317330154 SELECT t0.LENGTH_, t0.WEIGHT FROM STOCK t0 WHERE t0.INDEX_ = ?  [params=(String) 3]
> 3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> [0 ms] spent
> 3281  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 391649112> [0 ms] close
> 3344  TRACE  [main] openjpa.jdbc.JDBC - The batch limit is set to 100.
> 3344  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> executing prepstmnt 686827760 INSERT INTO PROGNOSISENTRY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, TIMESTAMP_) VALUES (?, ?, ?, ?, ?) [params=(String) 1400, (String) IN, (String) 3, (null) null, (String) 2009-12-09-17.34]
> 3547  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> [171 ms] spent
>
> <openjpa-2.0.0-M3-r422266:822833 fatal store error> org.apache.openjpa.util.StoreException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
>    at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2249)
>    at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2096)
>    at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1994)
>    at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1912)
>    at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
>    at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1436)
>    at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:895)
>    at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:557)
>    at test.persistParent(test.java:34)
>    at test.main(test.java:16)
> Caused by: <openjpa-2.0.0-M3-r422266:822833 fatal store error> org.apache.openjpa.util.ObjectExistsException: One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "1" constrains table "PROGNOSISENTRY" from having duplicate values for the index key.
> FailedObject: prepstmnt 686827760 INSERT INTO PROGNOSISENTRY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, TIMESTAMP_) VALUES (?, ?, ?, ?, ?) [org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement_]
>    at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4575)
>    at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4543)
>    at org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:541)
> ...

--
Constantine Kulak
wintermuteblog.blogspot.com




Re: Insert is called instead of Update when merge() with complex IDs

Posted by Fay Wang <fy...@yahoo.com>.
The em.merge will return the merged entity. 

    EntityA mergedEntity = em.merge(newEntity);

During your second merge call, did you call 
   em.merge(mergedEntity)
or 
  em.merge(newEntity)?

Fay



----- Original Message ----
From: Constantine Kulak <co...@mail.by>
To: users@openjpa.apache.org
Sent: Thu, October 29, 2009 4:19:11 AM
Subject: Insert is called instead of Update when merge() with complex IDs

Hello!

I need some help in the following situation - completely stuck with it :(
Can you please point me in some direction? Anyway, thanks in advance!
OpenJPA version is 2.0.0-M3.

So, I have three entities:

Prognosis contains many PrognosisEntry, and PrognosisEntry references some Stock. So, it's a many-to-many for Prognosis and Stock, having some additional data at PrognosisEntry join table. Fields:

Stock:
   index (PK)
   length

Prognosis:
   station (PK)
   type (PK)

PrognosisEntry:
   prognosis.station (FK, PK)
   prognosis.type (FK, PK)
   stock.index (FK, PK)
   localState
   timestamp

Relationship between Prognosis and PrognosisEntry is bidirectional (I really need Prognosis.getEntries() method). All IDs are taken from the real world and not generated because this data comes from the backend in XML and then deserialized using JAXB (annotations are removed from the sources below to simplify it). Then I do merge() and expect the data in the DB to be updated with the fresh one. When I call merge() for the 1st time (against the empty DB), all the necessary INSERTs are done. But when called for the 2nd time with the same data (I expect no changes to the DB), the exception is thrown because of the duplicate primary keys. Unexpectedly, it does INSERT instead of UPDATE in this case. The problem is seems to be with the PrognosisEntry-Stock relationship, because when I remove it (replacing reference to Stock in the PrognosisEntry with some dummy ID field) it starts working as expected (calls UPDATE). Exception and logs are given after the
 sources below.

***** 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() { ... }
}


***** Generated DDL:

CREATE TABLE PROGNOSIS (STATION VARCHAR(254) NOT NULL, TYPE_ VARCHAR(254) NOT NULL, PRIMARY KEY (STATION, TYPE_));
CREATE TABLE PROGNOSISENTRY (PROGNOSIS_STATION VARCHAR(254) NOT NULL, PROGNOSIS_TYPE_ VARCHAR(254) NOT NULL, STOCK_INDEX_ VARCHAR(254) NOT NULL, LOCALSTATE VARCHAR(254), TIMESTAMP_ VARCHAR(254), PRIMARY KEY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_));
CREATE TABLE STOCK (INDEX_ VARCHAR(254) NOT NULL, LENGTH_ VARCHAR(254), WEIGHT VARCHAR(254), PRIMARY KEY (INDEX_));
ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (PROGNOSIS_STATION, PROGNOSIS_TYPE_) REFERENCES PROGNOSIS (STATION, TYPE_);
ALTER TABLE PROGNOSISENTRY ADD FOREIGN KEY (STOCK_INDEX_) REFERENCES STOCK (INDEX_);


***** Executed SQL and exception:

3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> executing prepstmnt 379983526 SELECT t0.STATION, t0.TYPE_ FROM PROGNOSIS t0 WHERE t0.STATION = ? AND t0.TYPE_ = ?  [params=(String) 1400, (String) IN]
3063  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1004551136> [0 ms] spent
3078  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1004551136> [0 ms] close
3125  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> executing prepstmnt 1663984430 SELECT t0.PROGNOSIS_STATION, t0.PROGNOSIS_TYPE_, t0.STOCK_INDEX_, t0.LOCALSTATE, t1.INDEX_, t1.LENGTH_, t1.WEIGHT, t0.TIMESTAMP_ FROM PROGNOSISENTRY t0 LEFT OUTER JOIN STOCK t1 ON t0.STOCK_INDEX_ = t1.INDEX_ WHERE t0.PROGNOSIS_STATION = ? AND t0.PROGNOSIS_TYPE_ = ?  [params=(String) 1400, (String) IN]
3156  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1901752666> [31 ms] spent
3156  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1901752666> [0 ms] close
3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> executing prepstmnt 140118106 SELECT t0.LOCALSTATE, t1.STATION, t1.TYPE_, t2.INDEX_, t2.LENGTH_, t2.WEIGHT, t0.TIMESTAMP_ FROM PROGNOSISENTRY t0 LEFT OUTER JOIN PROGNOSIS t1 ON t0.PROGNOSIS_STATION = t1.STATION AND t0.PROGNOSIS_TYPE_ = t1.TYPE_ LEFT OUTER JOIN STOCK t2 ON t0.STOCK_INDEX_ = t2.INDEX_ WHERE t0.PROGNOSIS_STATION = ? AND t0.PROGNOSIS_TYPE_ = ? AND t0.STOCK_INDEX_ IS NULL  optimize for 1 row [params=(String) 1400, (String) IN]
3203  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1242843668> [0 ms] spent
3219  WARN   [main] openjpa.Runtime - Finder for "PrognosisEntry" is not cachable.
3219  TRACE  [main] openjpa.Runtime - finder-invalidate
3219  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 1242843668> [0 ms] close
3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> executing prepstmnt 317330154 SELECT t0.LENGTH_, t0.WEIGHT FROM STOCK t0 WHERE t0.INDEX_ = ?  [params=(String) 3]
3281  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 391649112> [0 ms] spent
3281  TRACE  [main] openjpa.jdbc.JDBC - <t 1183336072, conn 391649112> [0 ms] close
3344  TRACE  [main] openjpa.jdbc.JDBC - The batch limit is set to 100.
3344  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> executing prepstmnt 686827760 INSERT INTO PROGNOSISENTRY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, TIMESTAMP_) VALUES (?, ?, ?, ?, ?) [params=(String) 1400, (String) IN, (String) 3, (null) null, (String) 2009-12-09-17.34]
3547  TRACE  [main] openjpa.jdbc.SQL - <t 1183336072, conn 1494898970> [171 ms] spent

<openjpa-2.0.0-M3-r422266:822833 fatal store error> org.apache.openjpa.util.StoreException: The transaction has been rolled back.  See the nested exceptions for details on the errors that occurred.
   at org.apache.openjpa.kernel.BrokerImpl.newFlushException(BrokerImpl.java:2249)
   at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2096)
   at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1994)
   at org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1912)
   at org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
   at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1436)
   at org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:895)
   at org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:557)
   at test.persistParent(test.java:34)
   at test.main(test.java:16)
Caused by: <openjpa-2.0.0-M3-r422266:822833 fatal store error> org.apache.openjpa.util.ObjectExistsException: One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "1" constrains table "PROGNOSISENTRY" from having duplicate values for the index key.
FailedObject: prepstmnt 686827760 INSERT INTO PROGNOSISENTRY (PROGNOSIS_STATION, PROGNOSIS_TYPE_, STOCK_INDEX_, LOCALSTATE, TIMESTAMP_) VALUES (?, ?, ?, ?, ?) [org.apache.openjpa.jdbc.kernel.JDBCStoreManager$CancelPreparedStatement_]
   at org.apache.openjpa.jdbc.sql.DBDictionary.narrow(DBDictionary.java:4575)
   at org.apache.openjpa.jdbc.sql.DBDictionary.newStoreException(DBDictionary.java:4543)
   at org.apache.openjpa.jdbc.sql.DB2Dictionary.newStoreException(DB2Dictionary.java:541)
...

--
Constantine Kulak
wintermuteblog.blogspot.com