[ 
https://issues.apache.org/jira/browse/OPENJPA-1255?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12752742#action_12752742
 ] 

Fay Wang commented on OPENJPA-1255:
-----------------------------------

When MappedById is used, it can represent a single value primary key in the 
parent. According to JPA spec 2.0 (section 2.4):

"If the dependent entity class has a single primary key attribute (i.e, the 
relationship attribute) and the primary key of the parent entity is a simple 
primary key, the primary key of the dependent entity is a simple primary key of 
the same type as that of the parent entity (and neither EmbeddedId nor IdClass 
is specified). In this case, either (1) the relationship attribute is annotated 
Id, or (2) a separate
Id attribute is specified and the relationship attribute is annotated 
MappedById."

Your entity defintions are ok. The problem is with E1's constructor:

   public E1(E2 e, int i) {
        e2 = e;
        id = i;
    }

and in your test case, you have:

        E2 e2 = new E2(1);
        em.persist(e2);
        em.persist(new E1(e2,2));
        em.persist(new E1(e2,3));

As a result,
   "new E1(e2, 2) " ==> e2.id = 1 ==> e1.id is implicitly set to 1 but e1.id is 
explicitly set to 2. Similarly for "new E1(e2, 3) "

Note that E1's id is a derived id (i.e., this id is 'derived' from E2). Since 
the test deliberately provides two different values for the derived id, it is 
proper for Openjpa to throw exception to indicate this conflict.

The fix for the test case is to provide a constructor for E1 which will take 
only E2 as the parameter.

> InvalidStateException when using @MappedById and @JoinColumn on a 
> unidirectional @ManyToOne relationship
> --------------------------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-1255
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-1255
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: jdbc
>            Reporter: Rick Curtis
>
> I found that if I have a ManyToOne relationship using the JoinColumn and 
> MappedById annotations I receive the following exception:
> <openjpa-2.0.0-SNAPSHOT-r422266:804085M 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:2292)
>       at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:2140)
> .....
>       at 
> org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:553)
>       at main.Driver.main(Driver.java:67)
> Caused by: <openjpa-2.0.0-SNAPSHOT-r422266:804085M fatal user error> 
> org.apache.openjpa.util.InvalidStateException: Attempt to set column "E1.id" 
> to two different values: (class java.lang.Integer)"1", (class 
> java.lang.Integer)"2" This can occur when you fail to set both sides of a 
> two-sided relation between objects, or when you map different fields to the 
> same column, but you do not keep the values of these fields in synch.
>       at org.apache.openjpa.jdbc.sql.PrimaryRow.setObject(PrimaryRow.java:344)
>       at org.apache.openjpa.jdbc.sql.RowImpl.setInt(RowImpl.java:437)
>       at 
> org.apache.openjpa.jdbc.meta.strats.PrimitiveFieldStrategy.update(PrimitiveFieldStrategy.java:159)
>       at 
> org.apache.openjpa.jdbc.meta.strats.PrimitiveFieldStrategy.insert(PrimitiveFieldStrategy.java:119)
>       at 
> org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:608)
>       at 
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.insert(AbstractUpdateManager.java:230)
>       at 
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:162)
>       at 
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:95)
>       at 
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:76)
>       at 
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:675)
>       at 
> org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
>       ... 8 more
> I created this problem by running the following code in a JSE environment:
>       em.getTransaction().begin();
>       E2 e2 = new E2(1);
>       em.persist(e2);
>       em.persist(new E1(e2,2));
>       em.persist(new E1(e2,3));
>       em.getTransaction().commit();
> The domain model is as follows:
> @Entity
> public class E1 {
>     @Id
>     private int id;
>     @ManyToOne(cascade = CascadeType.PERSIST)
>     @MappedById
>     @JoinColumn(name = "something_fk")
>     private E2 e2;
>     public E1(E2 e, int i) {
>         e2 = e;
>         id = i;
>     }
>     public E1() {
>     }
> }//end E1
> @Entity
> public class E2 {
>     @Id
>     private int id;
>     public E2(int i) {
>         id = i;
>     }
>     public E2() {
>     }
> }// end E2

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

Reply via email to