Hi all, Vitals: Maven 3.0.3, Roo 1.2.1.RELEASE, OpenJPA 2.2.0, MySQL 5.1.x, Ubuntu 11.10 64-bit, JDK 6 (1.6.0_30) 64-bit
I'm getting an error with OpenJPA 2.2.0 that seems to have popped up a fair bit with other folks out on the Internet over the years. Can anyone see anything in my mappings that is either wrong or would cause this exception? I've been struggling with this for hours, trying all sorts of different mappings and nothing seems to help! Here's the exception snippet: ===== <openjpa-2.2.0-r422266:1244990 fatal user error> org.apache.openjpa.persistence.InvalidStateException: Attempt to set column "FloorRegion.version" to two different values: (null)"null", (class java.lang.Integer)"1" 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. ===== The class in question, FloorRegion, is the target of a unidirectional one-to-many relationship, owned by class FloorRegionList. Here's the relevant part of FloorRegionList: ===== @Table(name = "FloorRegionList") public class FloorRegionList implements HasCourtSize { @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH }) // unidirectional one-to-many using join column @JoinColumn(name = "owner", referencedColumnName = "id", nullable = true) protected List<FloorRegion> regions = new ArrayList<FloorRegion>(); ===== The FloorRegion class doesn't know anything whatsoever about FloorRegionList; it just has a couple of ints and five embedded FloorPoint instances: ===== @Table(name = "FloorRegion") public class FloorRegion implements HasCourtSize { @Column(nullable = false) protected int width; @Column(nullable = false) protected int length; @Embedded @AttributeOverrides({ @AttributeOverride(name = "w", column = @Column(name = "lfw", nullable = false)), @AttributeOverride(name = "l", column = @Column(name = "lfl", nullable = false)) }) protected FloorPoint leftFront; @Embedded @AttributeOverrides({ @AttributeOverride(name = "w", column = @Column(name = "lbw", nullable = false)), @AttributeOverride(name = "l", column = @Column(name = "lbl", nullable = false)) }) protected FloorPoint leftBack; @Embedded @AttributeOverrides({ @AttributeOverride(name = "w", column = @Column(name = "rfw", nullable = false)), @AttributeOverride(name = "l", column = @Column(name = "rfl", nullable = false)) }) protected FloorPoint rightFront; @Embedded @AttributeOverrides({ @AttributeOverride(name = "w", column = @Column(name = "rbw", nullable = false)), @AttributeOverride(name = "l", column = @Column(name = "rbl", nullable = false)) }) protected FloorPoint rightBack; @Embedded @AttributeOverrides({ @AttributeOverride(name = "w", column = @Column(name = "cw", nullable = false)), @AttributeOverride(name = "l", column = @Column(name = "cl", nullable = false)) }) protected FloorPoint center; ===== Here's my persistence.xml (note addition of foreign key constraints): ===== <?xml version="1.0" encoding="UTF-8" standalone="no"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL"> <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> <properties> <property name="openjpa.jdbc.DBDictionary" value="org.apache.openjpa.jdbc.sql.MySQLDictionary" /> <!-- value="buildSchema" to runtime forward map the DDL SQL; value="validate" makes no changes to the database --> <property name="openjpa.jdbc.SynchronizeMappings" value="validate" /> <property name="openjpa.RuntimeUnenhancedClasses" value="unsupported" /> <property name="openjpa.jdbc.MappingDefaults" value="ForeignKeyDeleteAction=restrict, JoinForeignKeyDeleteAction=restrict" /> </properties> </persistence-unit> </persistence> ===== Here's a snippet from my pom.xml that has to do with OpenJPA enhancement. It enhances, generates a clean schema DDL file, a differential one, connects to the database & refreshes it (during the process-classes phase), and then during the post-integration-test phase, runs a main class that seeds the database with an initial set of entities. ===== <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>openjpa-maven-plugin</artifactId> <version>1.2</version> <executions> <execution> <id>enhance-classes</id> <phase>process-classes</phase> <goals> <goal>enhance</goal> </goals> <configuration> <includes>${statthing.entities.ant.pathspec}</includes> <excludes>**/*_Roo_*.class</excludes> <addDefaultConstructor>true</addDefaultConstructor> </configuration> </execution> <execution> <id>generate-ddl-file-complete</id> <phase>process-classes</phase> <goals> <goal>sql</goal> </goals> <configuration> <includes>${statthing.entities.ant.pathspec}</includes> <excludes>**/*_Roo_*.class</excludes> <sqlAction>build</sqlAction> <foreignKeys>true</foreignKeys> <sqlFile>${statthing.db.ddl.file.complete}</sqlFile> </configuration> </execution> <execution> <id>generate-ddl-file-diff</id> <phase>process-classes</phase> <goals> <goal>sql</goal> </goals> <configuration> <includes>${statthing.entities.ant.pathspec}</includes> <excludes>**/*_Roo_*.class</excludes> <sqlAction>refresh</sqlAction> <foreignKeys>true</foreignKeys> <sqlFile>${statthing.db.ddl.file.diff}</sqlFile> <connectionDriverName>${statthing.db.connection.driver.name}</connectionDriverName> <connectionDriverName>com.mchange.v2.c3p0.ComboPooledDataSource</connectionDriverName> <connectionProperties>${statthing.db.connection.properties}</connectionProperties> </configuration> </execution> <execution> <id>generate-ddl-db</id> <phase>process-classes</phase> <goals> <goal>sql</goal> </goals> <configuration> <includes>${statthing.entities.ant.pathspec}</includes> <excludes>**/*_Roo_*.class</excludes> <sqlAction>refresh</sqlAction> <foreignKeys>true</foreignKeys> <modifyDatabase>true</modifyDatabase> <connectionDriverName>${statthing.db.connection.driver.name}</connectionDriverName> <connectionDriverName>com.mchange.v2.c3p0.ComboPooledDataSource</connectionDriverName> <connectionProperties>${statthing.db.connection.properties}</connectionProperties> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>org.apache.openjpa</groupId> <artifactId>openjpa</artifactId> <version>2.1.1</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jms_1.1_spec</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <id>seed-database</id> <goals> <goal>exec</goal> </goals> <phase>post-integration-test</phase> </execution> </executions> <configuration> <executable>java</executable> <classpathScope>test</classpathScope> <arguments> <argument>-Xdebug</argument> <argument>-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005</argument> <argument>-classpath</argument> <classpath /> <argument>com.statthing.model.volleyball.seeder.Seeder</argument> </arguments> </configuration> </plugin> ===== Thanks, Matthew -- @matthewadams12 mailto:matt...@matthewadams.me skype:matthewadams12 yahoo:matthewadams aol:matthewadams12 google-talk:matthewadam...@gmail.com msn:matt...@matthewadams.me http://matthewadams.me http://www.linkedin.com/in/matthewadams