Hi,

1. Reconfirmed the error.

2. Found no related issue in OpenJPA JIRA.

3. The following patch can be applied to fix it.

Index:
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
===================================================================
---
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
     
(revision 618739)
+++
openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/EmbedFieldStrategy.java
     
(working copy)
@@ -165,7 +165,8 @@
         FieldMapping[] fields =
field.getEmbeddedMapping().getFieldMappings();
         for (int i = 0; i < fields.length; i++)
             if (!Boolean.TRUE.equals(fields[i].isCustomInsert(em, store)))
-                fields[i].insert(em, store, rm);
+                if (!fields[i].isPrimaryKey())
+                    fields[i].insert(em, store, rm);

         if (field.getColumnIO().isInsertable(0, true))
             setNullIndicatorColumn(sm, row);

Cedric Hurst wrote:
> 
> I'm not sure if this is a genuine bug or if I'm doing something wrong, but
> I thought I'd check here before I open a JIRA.
> 
> BaseEntity is a @MappedSuperclass which holds only an id property
> Address is an @Entity which extends BaseAddress and holds values for
> streetAddress, city, state, zip.  It also has a property called geocode
> which is an @Embedded type (see next)
> Geocode is an @Embeddable which is embedded inside Address and holds
> values for the latitude and longitude values
> 
> Go here to see the actual code for the JPA objects:
> 
> http://trac2.assembla.com/d5Z24gWSer3lvHabIlDkbG/browser/OpenJPA/EmbeddableTest/src/entity
> 
> Now, in my test java application, I attempt to create a new Address
> providing values for streetAddress, city, state, zip but not specifying
> anything for geocode:
> 
> http://trac2.assembla.com/d5Z24gWSer3lvHabIlDkbG/browser/OpenJPA/EmbeddableTest/src/runtime/JpaTest.java?rev=32
> 
> When I attempt to persist this Address object, I get an
> InvalidStateException.  Here is the log:
> 
> 47  CustomerTest  INFO   [main] openjpa.Runtime - Starting OpenJPA
> 1.1.0-SNAPSHOT
> 156  CustomerTest  INFO   [main] openjpa.jdbc.JDBC - Using dictionary
> class "org.apache.openjpa.jdbc.sql.DerbyDictionary".
> 1469  CustomerTest  WARN   [main] openjpa.MetaData - No setter was found
> for method longtitude in type entity.Geocode while searching for
> persistent properties. This method will be ignored. If you intended for
> this to be persistent, please add a corresponding setter, or switch to
> field access for this type hierarchy.
> 1484  CustomerTest  WARN   [main] openjpa.MetaData - No setter was found
> for method longtitude in type entity.Geocode while searching for
> persistent properties. This method will be ignored. If you intended for
> this to be persistent, please add a corresponding setter, or switch to
> field access for this type hierarchy.
> 1656  CustomerTest  INFO   [main] openjpa.Enhance - Creating subclass for
> "[class entity.Address, class entity.Geocode, class entity.BaseEntity]".
> This means that your application will be less efficient and will consume
> more memory than it would if you ran the OpenJPA enhancer. Additionally,
> lazy loading will not be available for one-to-one and many-to-one
> persistent attributes in types using field access; they will be loaded
> eagerly instead.
> 1703  CustomerTest  WARN   [main] openjpa.MetaData - No setter was found
> for method longtitude in type entity.Geocode while searching for
> persistent properties. This method will be ignored. If you intended for
> this to be persistent, please add a corresponding setter, or switch to
> field access for this type hierarchy.
> 1719  CustomerTest  WARN   [main] openjpa.MetaData - No setter was found
> for method longtitude in type entity.Geocode while searching for
> persistent properties. This method will be ignored. If you intended for
> this to be persistent, please add a corresponding setter, or switch to
> field access for this type hierarchy.
> 1766  CustomerTest  WARN   [main] openjpa.MetaData - No setter was found
> for method longtitude in type entity.Geocode while searching for
> persistent properties. This method will be ignored. If you intended for
> this to be persistent, please add a corresponding setter, or switch to
> field access for this type hierarchy.
> 1891  CustomerTest  TRACE  [main] openjpa.jdbc.SQL - <t 1090273532, conn
> 1509972480> executing prepstmnt 1293569306 SELECT SEQUENCE_VALUE FROM
> OPENJPA_SEQUENCE_TABLE WHERE ID = ? FOR UPDATE WITH RR [params=(int) 0]
> 1891  CustomerTest  TRACE  [main] openjpa.jdbc.SQL - <t 1090273532, conn
> 1509972480> [0 ms] spent
> 1891  CustomerTest  TRACE  [main] openjpa.jdbc.SQL - <t 1090273532, conn
> 1509972480> executing prepstmnt 559423832 UPDATE OPENJPA_SEQUENCE_TABLE
> SET SEQUENCE_VALUE = ? WHERE ID = ? AND SEQUENCE_VALUE = ? [params=(long)
> 901, (int) 0, (long) 851]
> 1906  CustomerTest  TRACE  [main] openjpa.jdbc.SQL - <t 1090273532, conn
> 1509972480> [15 ms] spent
> 2000  CustomerTest  TRACE  [main] openjpa.jdbc.SQL - <t 1090273532, conn
> 1181632110> executing prepstmnt 1721001620 INSERT INTO Address (id, city)
> VALUES (?, ?) [params=(long) 851, (String) Chicago]
> 2000  CustomerTest  TRACE  [main] openjpa.jdbc.SQL - <t 1090273532, conn
> 1181632110> [0 ms] spent
> Exception in thread "main" <openjpa-1.1.0-SNAPSHOT-r420667:616905 fatal
> store error> org.apache.openjpa.persistence.RollbackException: The
> transaction has been rolled back.  See the nested exceptions for details
> on the errors that occurred.
>       at
> org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:494)
>       at runtime.JpaTest.main(JpaTest.java:24)
> Caused by: <openjpa-1.1.0-SNAPSHOT-r420667:616905 fatal general error>
> org.apache.openjpa.persistence.PersistenceException: 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:2145)
>       at org.apache.openjpa.kernel.BrokerImpl.flush(BrokerImpl.java:1992)
>       at org.apache.openjpa.kernel.BrokerImpl.flushSafe(BrokerImpl.java:1890)
>       at
> org.apache.openjpa.kernel.BrokerImpl.beforeCompletion(BrokerImpl.java:1808)
>       at
> org.apache.openjpa.kernel.LocalManagedRuntime.commit(LocalManagedRuntime.java:81)
>       at org.apache.openjpa.kernel.BrokerImpl.commit(BrokerImpl.java:1332)
>       at
> org.apache.openjpa.kernel.DelegatingBroker.commit(DelegatingBroker.java:861)
>       at
> org.apache.openjpa.persistence.EntityManagerImpl.commit(EntityManagerImpl.java:483)
>       ... 1 more
> Caused by: <openjpa-1.1.0-SNAPSHOT-r420667:616905 fatal user error>
> org.apache.openjpa.persistence.InvalidStateException: Attempt to set
> column "Address.id" to two different values: (class java.lang.Long)"851",
> (null)"null" 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:338)
>       at org.apache.openjpa.jdbc.sql.RowImpl.setNull(RowImpl.java:456)
>       at
> org.apache.openjpa.jdbc.meta.strats.EmbedFieldStrategy$EmbeddedRow.setNull(EmbedFieldStrategy.java:1400)
>       at
> org.apache.openjpa.jdbc.meta.strats.HandlerStrategies.set(HandlerStrategies.java:136)
>       at
> org.apache.openjpa.jdbc.meta.strats.HandlerStrategies.set(HandlerStrategies.java:93)
>       at
> org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy.insert(HandlerFieldStrategy.java:126)
>       at
> org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:562)
>       at
> org.apache.openjpa.jdbc.meta.strats.EmbedFieldStrategy.insert(EmbedFieldStrategy.java:168)
>       at
> org.apache.openjpa.jdbc.meta.strats.EmbedFieldStrategy.insert(EmbedFieldStrategy.java:147)
>       at
> org.apache.openjpa.jdbc.meta.FieldMapping.insert(FieldMapping.java:562)
>       at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.insert(AbstractUpdateManager.java:203)
>       at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.populateRowManager(AbstractUpdateManager.java:145)
>       at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:85)
>       at
> org.apache.openjpa.jdbc.kernel.AbstractUpdateManager.flush(AbstractUpdateManager.java:72)
>       at
> org.apache.openjpa.jdbc.kernel.JDBCStoreManager.flush(JDBCStoreManager.java:549)
>       at
> org.apache.openjpa.kernel.DelegatingStoreManager.flush(DelegatingStoreManager.java:130)
>       ... 8 more
> 
> I've tested a few permutations and this is what I've found:
> 
> ===
> 
> If I try to set geocode values for the Address object before persisting...
> 
> http://trac2.assembla.com/d5Z24gWSer3lvHabIlDkbG/browser/OpenJPA/EmbeddableTest/src/runtime/JpaTest.java?rev=29
> 
> ... the address object still fails to persist.
> 
> ===
> 
> If I remove the Address.geocode embedded object...
> 
> http://trac2.assembla.com/d5Z24gWSer3lvHabIlDkbG/browser/OpenJPA/EmbeddableTest/src/entity/Address.java?rev=31
> 
> ... the address object persists successfully.
> 
> ===
> 
> If I change the Address class so it does not extend BaseEntity (and
> instead provides its own @Id property)...
> 
> http://trac2.assembla.com/d5Z24gWSer3lvHabIlDkbG/browser/OpenJPA/EmbeddableTest/src/entity/Address.java?rev=30
> 
> ...the address object persists successfully
> 
> ===
> 
> Thus, it seems to be an issue specifically related to the pattern of an
> @Embeddable object inside an @Entity which extends a @MappedSuperclass.
> 
> I've tested this out on both openjpa-1.1.0-SNAPSHOT and openjpa-1.0.0.
> 

-- 
View this message in context: 
http://www.nabble.com/Problem-with-MappedSuperclass-Entity-Embeddable-object-graph-tp15298457p15299690.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Reply via email to