Seeing one new test failure on MS SQL Server w/ JDK6, Oracle w/ JDK 6 and DB2 w/ SDK 6 after this commit - From MSSQL - org.apache.openjpa.persistence.PersistenceException: Column, parameter, or variable #3: Cannot find data type OTHER. {stmnt 16364317 CREATE TABLE Bi_1ToM_JT (bid BIGINT NOT NULL, name VARCHAR(255), id OTHER, PRIMARY KEY (bid))} [code=2715, state=S0007] at org.apache.openjpa.jdbc.meta.MappingTool.record(MappingTool.java:553) at org.apache.openjpa.jdbc.meta.MappingTool.record(MappingTool.java:453) at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:158) . . . From DB2 - TestSpecCompatibilityOptions.testOneToManyRelation(org.apache.openjpa.persistence.compat) org.apache.openjpa.persistence.PersistenceException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=OTHER, DRIVER=3.50.152 {stmnt 1069825988 CREATE TABLE Bi_1ToM_JT (bid BIGINT NOT NULL, name VARCHAR(254), ID OTHER, PRIMARY KEY (bid))} [code=-204, state=42704] at org.apache.openjpa.jdbc.meta.MappingTool.record(MappingTool.java:553) at org.apache.openjpa.jdbc.meta.MappingTool.record(MappingTool.java:453) Please wait... Show stacktrace » « Hide stacktrace org.apache.openjpa.persistence.PersistenceException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=OTHER, DRIVER=3.50.152 {stmnt 1069825988 CREATE TABLE Bi_1ToM_JT (bid BIGINT NOT NULL, name VARCHAR(254), ID OTHER, PRIMARY KEY (bid))} [code=-204, state=42704] at org.apache.openjpa.jdbc.meta.MappingTool.record(MappingTool.java:553) at org.apache.openjpa.jdbc.meta.MappingTool.record(MappingTool.java:453) at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:158) at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:162) at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newBrokerImpl(JDBCBrokerFactory.java:118) at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:201) at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:152) at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:199) at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:150) at org.apache.openjpa.persistence.compat.TestSpecCompatibilityOptions.testOneToManyRelation(TestSpecCompatibilityOptions.java:176) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:599) at junit.framework.TestCase.runTest(TestCase.java:154) at org.apache.openjpa.persistence.test.AbstractPersistenceTestCase.runTest(AbstractPersistenceTestCase.java:514) at junit.framework.TestCase.runBare(TestCase.java:127) at org.apache.openjpa.persistence.test.AbstractPersistenceTestCase.runBare(AbstractPersistenceTestCase.java:501) at org.apache.openjpa.persistence.test.AbstractPersistenceTestCase.runBare(AbstractPersistenceTestCase.java:477) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:118) at org.apache.openjpa.persistence.test.AbstractPersistenceTestCase.run(AbstractPersistenceTestCase.java:177) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at sun.reflect.GeneratedMethodAccessor53.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:599) at org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140) at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127) at org.apache.maven.surefire.Surefire.run(Surefire.java:177) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:599) at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:345) at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1009) Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: DB2 SQL Error: SQLCODE=-204, SQLSTATE=42704, SQLERRMC=OTHER, DRIVER=3.50.152 {stmnt 1069825988 CREATE TABLE Bi_1ToM_JT (bid BIGINT NOT NULL, name VARCHAR(254), ID OTHER, PRIMARY KEY (bid))} [code=-204, state=42704] at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.wrap(LoggingConnectionDecorator.java:254) at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator.access$700(LoggingConnectionDecorator.java:70) at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection$LoggingStatement.executeUpdate(LoggingConnectionDecorator.java:944) at org.apache.openjpa.lib.jdbc.DelegatingStatement.executeUpdate(DelegatingStatement.java:136) at org.apache.openjpa.jdbc.schema.SchemaTool.executeSQL(SchemaTool.java:1202) at org.apache.openjpa.jdbc.schema.SchemaTool.createTable(SchemaTool.java:960) at org.apache.openjpa.jdbc.schema.SchemaTool.add(SchemaTool.java:537) at org.apache.openjpa.jdbc.schema.SchemaTool.add(SchemaTool.java:345) at org.apache.openjpa.jdbc.schema.SchemaTool.run(SchemaTool.java:322) at org.apache.openjpa.jdbc.meta.MappingTool.record(MappingTool.java:501) ... 38 more ------- Stderr: ------- 1 persistence_2_0 INFO [main] openjpa.Runtime - Starting OpenJPA 2.0.0-SNAPSHOT 334 persistence_2_0 INFO [main] openjpa.jdbc.JDBC - Using dictionary class "org.apache.openjpa.jdbc.sql.DB2Dictionary" (DB2/NT SQL09052 ,IBM DB2 JDBC Universal Driver Architecture 3.50.152). faywang@apache.org wrote: > Author: faywang > Date: Fri Sep 18 21:53:47 2009 > New Revision: 816795 > > URL: http://svn.apache.org/viewvc?rev=816795&view=rev > Log: > OPENJPA-1253: support non-default One-To-Many mappings > > Added: > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_JT.java (with props) > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MFK.java (with props) > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MJT.java (with props) > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1MFK.java (with props) > Modified: > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java > openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyTableFieldStrategy.java > openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java > openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java > openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java > openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_FK.java > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC.java > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_FK.java > openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_JT.java > openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java > openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java > openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java > > Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java (original) > +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/MappingRepository.java Fri Sep 18 21:53:47 2009 > @@ -949,8 +949,17 @@ > * field should use an inverse foreign key or an association table mapping. > */ > private boolean useInverseKeyMapping(FieldMapping field) { > + OpenJPAConfiguration conf = field.getRepository().getConfiguration(); > + boolean isNonDefaultMappingAllowed = field.getRepository(). > + getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf); > FieldMapping mapped = field.getMappedByMapping(); > if (mapped != null) { > + // JPA 2.0: non-default mapping: bi-/1-M/JoinTable ==> join table strategy > + FieldMappingInfo info = field.getMappingInfo(); > + if (isNonDefaultMappingAllowed && > + field.getAssociationType() == FieldMetaData.ONE_TO_MANY && > + info.getTableName() != null) > + return false; > if (mapped.getTypeCode() == JavaTypes.PC) > return true; > if (mapped.getElement().getTypeCode() == JavaTypes.PC) > @@ -968,17 +977,16 @@ > boolean useInverseKeyMapping = info.getTableName() == null && info.getColumns().isEmpty() > && !elem.getValueInfo().getColumns().isEmpty(); > > - OpenJPAConfiguration conf = field.getRepository().getConfiguration(); > - boolean isNonDefaultMappingAllowed = field.getRepository(). > - getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf); > - if (isNonDefaultMappingAllowed && field.getValueInfo().getColumns().size() > 0) { > - // uni-/M-1/joinColumn ==> useInverseKeyMapping (foreign key strategy) > + // JPA 2.0: non-default mapping: uni-/1-M/JoinColumn ==> foreign key strategy > + if (isNonDefaultMappingAllowed && > + field.getValueInfo().getColumns().size() > 0 && > + field.getAssociationType() == FieldMetaData.ONE_TO_MANY) { > field.getElementMapping().getValueInfo().setColumns(field.getValueInfo().getColumns()); > return true; > } > return useInverseKeyMapping; > } > - > + > /** > * Check the given value against mapped strategies. > */ > > Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java (original) > +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java Fri Sep 18 21:53:47 2009 > @@ -34,6 +34,7 @@ > import org.apache.openjpa.jdbc.meta.ClassMapping; > import org.apache.openjpa.jdbc.meta.Embeddable; > import org.apache.openjpa.jdbc.meta.FieldMapping; > +import org.apache.openjpa.jdbc.meta.FieldMappingInfo; > import org.apache.openjpa.jdbc.meta.FieldStrategy; > import org.apache.openjpa.jdbc.meta.Joinable; > import org.apache.openjpa.jdbc.meta.MappingInfo; > @@ -82,6 +83,7 @@ > (RelationFieldStrategy.class); > > private Boolean _fkOid = null; > + boolean _isBiOneToManyJoinTable = false; > > public void map(boolean adapt) { > if (field.getTypeCode() != JavaTypes.PC || field.isEmbeddedPC()) > @@ -136,9 +138,9 @@ > return; > } else { // this could be the owner in a bi-directional relation > OpenJPAConfiguration conf = field.getRepository().getConfiguration(); > - boolean isJoinColumnAllowedForToManyRelation = field.getRepository(). > - getMetaDataFactory().getDefaults().isJoinColumnAllowedForToManyRelation(conf); > - if (isJoinColumnAllowedForToManyRelation) { > + boolean isNonDefaultMappingAllowed = field.getRepository(). > + getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf); > + if (isNonDefaultMappingAllowed) { > ClassMapping inverse = field.getValueMapping().getTypeMapping(); > FieldMapping[] fmds = inverse.getFieldMappings(); > for (int i = 0; i < fmds.length; i++) { > @@ -147,10 +149,11 @@ > if (typeCode == JavaTypes.ARRAY || > typeCode == JavaTypes.COLLECTION || > typeCode == JavaTypes.MAP) { > - // this is a bi-directional oneToMany relation > - ValueMappingInfo info = field.getValueInfo(); > - if (info.getColumns().size() == 0) > - info.setColumns(fmds[i].getValueInfo().getColumns()); > + // this is a bi-directional oneToMany relation with > + // @JoinTable annotation ==> join table strategy > + // ==> should not mapped in the owner's table > + FieldMappingInfo info = fmds[i].getMappingInfo(); > + _isBiOneToManyJoinTable = (info.getTableName() != null ? true : false); > } > break; > } > @@ -180,9 +183,11 @@ > if (field.getMappedByIdValue() != null) > setMappedByIdColumns(); > > - ForeignKey fk = vinfo.getTypeJoin(field, field.getName(), true, > - adapt); > - field.setForeignKey(fk); > + if (!_isBiOneToManyJoinTable) { > + ForeignKey fk = vinfo.getTypeJoin(field, field.getName(), true, > + adapt); > + field.setForeignKey(fk); > + } > field.setColumnIO(vinfo.getColumnIO()); > if (vinfo.getJoinDirection() == vinfo.JOIN_INVERSE) > field.setJoinDirection(field.JOIN_INVERSE); > @@ -290,7 +295,8 @@ > else { > Row row = field.getRow(sm, store, rm, Row.ACTION_INSERT); > if (row != null) { > - field.setForeignKey(row, rel); > + if (!_isBiOneToManyJoinTable) > + field.setForeignKey(row, rel); > // this is for bi-directional maps, the key and value of the > // map are stored in the table of the mapped-by entity > setMapKey(sm, rel, store, row); > @@ -376,7 +382,8 @@ > Row.ACTION_DELETE : Row.ACTION_UPDATE; > Row row = field.getRow(sm, store, rm, action); > if (row != null) { > - field.setForeignKey(row, rel); > + if (!_isBiOneToManyJoinTable) > + field.setForeignKey(row, rel); > // this is for bi-directional maps, the key and value of the > // map are stored in the table of the mapped-by entity > setMapKey(sm, rel, store, row); > @@ -566,6 +573,9 @@ > > public void selectEagerJoin(Select sel, OpenJPAStateManager sm, > JDBCStore store, JDBCFetchConfiguration fetch, int eagerMode) { > + if (_isBiOneToManyJoinTable) > + return; > + > // limit the eager mode to single on recursive eager fetching b/c > // at this point the select has been modified and an attempt to > // clone it for a to-many eager select can result in a clone that > @@ -715,7 +725,7 @@ > // get the related object's oid > ClassMapping relMapping = field.getTypeMapping(); > Object oid = null; > - if (relMapping.isMapped()) { > + if (relMapping.isMapped() && !_isBiOneToManyJoinTable) { > oid = relMapping.getObjectId(store, res, field.getForeignKey(), > field.getPolymorphic() != ValueMapping.POLY_FALSE, null); > } else { > > Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java (original) > +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyInverseKeyFieldStrategy.java Fri Sep 18 21:53:47 2009 > @@ -108,11 +108,15 @@ > > public void map(boolean adapt) { > OpenJPAConfiguration conf = field.getRepository().getConfiguration(); > - boolean isJoinColumnAllowedForToManyRelation = field.getRepository(). > - getMetaDataFactory().getDefaults().isJoinColumnAllowedForToManyRelation(conf); > - if (!isJoinColumnAllowedForToManyRelation) > + boolean isNonDefaultMappingAllowed = field.getRepository(). > + getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf); > + FieldMapping mapped = field.getMappedByMapping(); > + > + // JPA 2.0 allows non-default mapping: Uni-/1-M/@JoinColumn ==> foreign key strategy > + // Bi-/1-M/@JoinColumn should result in exception > + if (!isNonDefaultMappingAllowed || mapped != null) { > field.getValueInfo().assertNoSchemaComponents(field, !adapt); > - > + } > field.getKeyMapping().getValueInfo().assertNoSchemaComponents > (field.getKey(), !adapt); > > @@ -122,7 +126,6 @@ > throw new MetaDataException(_loc.get("not-elem-relation", field)); > > // check for named inverse > - FieldMapping mapped = field.getMappedByMapping(); > FieldMappingInfo finfo = field.getMappingInfo(); > ValueMappingInfo vinfo = elem.getValueInfo(); > boolean criteria = vinfo.getUseClassCriteria(); > > Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyTableFieldStrategy.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyTableFieldStrategy.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyTableFieldStrategy.java (original) > +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationToManyTableFieldStrategy.java Fri Sep 18 21:53:47 2009 > @@ -22,6 +22,7 @@ > import java.util.Collection; > import java.util.Iterator; > > +import org.apache.openjpa.conf.OpenJPAConfiguration; > import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; > import org.apache.openjpa.jdbc.kernel.JDBCStore; > import org.apache.openjpa.jdbc.meta.ClassMapping; > @@ -39,6 +40,7 @@ > import org.apache.openjpa.kernel.OpenJPAStateManager; > import org.apache.openjpa.kernel.StoreContext; > import org.apache.openjpa.lib.util.Localizer; > +import org.apache.openjpa.meta.FieldMetaData; > import org.apache.openjpa.meta.JavaTypes; > import org.apache.openjpa.util.ChangeTracker; > import org.apache.openjpa.util.MetaDataException; > @@ -53,6 +55,8 @@ > public abstract class RelationToManyTableFieldStrategy > extends StoreCollectionFieldStrategy { > > + boolean _isBiOneToManyJoinTable = false; > + > private static final Localizer _loc = Localizer.forPackage > (RelationToManyTableFieldStrategy.class); > > @@ -105,46 +109,62 @@ > FieldMapping mapped = field.getMappedByMapping(); > ValueMappingInfo vinfo = elem.getValueInfo(); > boolean criteria = vinfo.getUseClassCriteria(); > + > + OpenJPAConfiguration conf = field.getRepository().getConfiguration(); > + boolean isNonDefaultMappingAllowed = field.getRepository(). > + getMetaDataFactory().getDefaults().isNonDefaultMappingAllowed(conf); > + // Bi-directional oneToMany relation with > + // @JoinTable annotation ==> join table strategy > + // ==> should not mapped in the owner's table > if (mapped != null) { > - if (mapped.getElement().getTypeCode() != JavaTypes.PC) > - throw new MetaDataException(_loc.get("not-inv-relation-coll", > - field, mapped)); > - field.getMappingInfo().assertNoSchemaComponents(field, !adapt); > - vinfo.assertNoSchemaComponents(elem, !adapt); > - mapped.resolve(mapped.MODE_META | mapped.MODE_MAPPING); > - > - if (!mapped.isMapped() || mapped.isSerialized()) > - throw new MetaDataException(_loc.get("mapped-by-unmapped", > - field, mapped)); > - > - field.setJoinForeignKey(mapped.getElementMapping(). > - getForeignKey(field.getDefiningMapping())); > - elem.setForeignKey(mapped.getJoinForeignKey()); > - elem.setUseClassCriteria(criteria); > - field.setOrderColumn(mapped.getOrderColumn()); > - return; > + _isBiOneToManyJoinTable = > + field.getAssociationType() == FieldMetaData.ONE_TO_MANY && > + field.getMappingInfo().getTableName() != null ? true : false; > + > + if (!isNonDefaultMappingAllowed || !_isBiOneToManyJoinTable) { > + // JPA 2.0: Bi-/OneToMany/@JoinTable ==> join table strategy is allowed > + if (mapped.getElement().getTypeCode() != JavaTypes.PC) { > + throw new MetaDataException(_loc.get("not-inv-relation-coll", > + field, mapped)); > + } > + field.getMappingInfo().assertNoSchemaComponents(field, !adapt); > + vinfo.assertNoSchemaComponents(elem, !adapt); > + > + mapped.resolve(mapped.MODE_META | mapped.MODE_MAPPING); > + if (!mapped.isMapped() || mapped.isSerialized()) > + throw new MetaDataException(_loc.get("mapped-by-unmapped", > + field, mapped)); > + field.setJoinForeignKey(mapped.getElementMapping(). > + getForeignKey(field.getDefiningMapping())); > + elem.setForeignKey(mapped.getJoinForeignKey()); > + elem.setUseClassCriteria(criteria); > + field.setOrderColumn(mapped.getOrderColumn()); > + return; > + } > } > > - field.mapJoin(adapt, true); > - if (elem.getTypeMapping().isMapped()) { > - ForeignKey fk = vinfo.getTypeJoin(elem, "element", false, adapt); > - elem.setForeignKey(fk); > - elem.setColumnIO(vinfo.getColumnIO()); > - } else > - RelationStrategies.mapRelationToUnmappedPC(elem, "element", adapt); > - elem.setUseClassCriteria(criteria); > - elem.mapConstraints("element", adapt); > - > - FieldMappingInfo finfo = field.getMappingInfo(); > - Column orderCol = finfo.getOrderColumn(field, field.getTable(), adapt); > - field.setOrderColumn(orderCol); > - field.setOrderColumnIO(finfo.getColumnIO()); > - field.mapPrimaryKey(adapt); > + if (mapped == null || (_isBiOneToManyJoinTable && isNonDefaultMappingAllowed)) { > + field.mapJoin(adapt, true); > + if (elem.getTypeMapping().isMapped()) { > + ForeignKey fk = vinfo.getTypeJoin(elem, "element", false, adapt); > + elem.setForeignKey(fk); > + elem.setColumnIO(vinfo.getColumnIO()); > + } else > + RelationStrategies.mapRelationToUnmappedPC(elem, "element", adapt); > + elem.setUseClassCriteria(criteria); > + elem.mapConstraints("element", adapt); > + > + FieldMappingInfo finfo = field.getMappingInfo(); > + Column orderCol = finfo.getOrderColumn(field, field.getTable(), adapt); > + field.setOrderColumn(orderCol); > + field.setOrderColumnIO(finfo.getColumnIO()); > + field.mapPrimaryKey(adapt); > + } > } > > public void insert(OpenJPAStateManager sm, JDBCStore store, RowManager rm) > throws SQLException { > - if (field.getMappedBy() == null) > + if (field.getMappedBy() == null || _isBiOneToManyJoinTable) > insert(sm, rm, sm.fetchObject(field.getIndex())); > } > > @@ -175,7 +195,7 @@ > > public void update(OpenJPAStateManager sm, JDBCStore store, RowManager rm) > throws SQLException { > - if (field.getMappedBy() != null) > + if (field.getMappedBy() != null && !_isBiOneToManyJoinTable) > return; > > Object obj = sm.fetchObject(field.getIndex()); > > Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (original) > +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java Fri Sep 18 21:53:47 2009 > @@ -63,7 +63,6 @@ > private boolean _autoOff = true; > private boolean _superclassDiscriminatorStrategyByDefault = true; > private boolean _isAbstractMappingUniDirectional = false; > - private boolean _isJoinColumnAllowedForToManyRelation = false; > private boolean _isNonDefaultMappingAllowed = false; > > /** > @@ -453,32 +452,6 @@ > } > > /** > - * Whether OpenJPA allows JoinColumn annotation in conjunction with > - * OneToMany annotation. > - * Prior to OpenJPA 2.0, the JoinColumn annotation is not allowed for > - * is OneToMany relation. JPA 2.0 spec relaxes this restriction. > - * > - * @param isJoinColumnAllowedForToManyRelation true if JoinColumn is > - * allowed for OneToMany relation > - * @since 2.0.0 > - */ > - public void setJoinColumnAllowedForToManyRelation(boolean isJoinColumnAllowedForToManyRelation) { > - _isJoinColumnAllowedForToManyRelation = isJoinColumnAllowedForToManyRelation; > - } > - > - /** > - * Whether OpenJPA allows JoinColumn annotation in conjunction with > - * OneToMany annotation. > - * Prior to OpenJPA 2.0, the JoinColumn annotation is not allowed for > - * is OneToMany relation. JPA 2.0 spec relaxes this restriction. The > - * default value is false. > - * @since 2.0.0 > - */ > - public boolean isJoinColumnAllowedForToManyRelation() { > - return _isJoinColumnAllowedForToManyRelation; > - } > - > - /** > * Whether OpenJPA allows non-default entity relationship mapping. > * Prior to OpenJPA 2.0, the non-default entity relationship mapping > * is not allowed. JPA 2.0 spec relaxes this restriction. The > > Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java (original) > +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/FieldMetaData.java Fri Sep 18 21:53:47 2009 > @@ -114,6 +114,11 @@ > * Constant specifying the management level of a field. > */ > public static final int MANAGE_NONE = 0; > + > + public static final int ONE_TO_ONE = 1; > + public static final int ONE_TO_MANY = 2; > + public static final int MANY_TO_ONE = 3; > + public static final int MANY_TO_MANY = 4; > > private static final Localizer _loc = Localizer.forPackage > (FieldMetaData.class); > @@ -213,6 +218,7 @@ > // indicate if this field is used by other field as "order by" value > private boolean _usedInOrderBy = false; > private boolean _isElementCollection = false; > + private int _associationType; > > /** > * Constructor. > @@ -2217,5 +2223,14 @@ > ClassMetaData owner = getDeclaringMetaData(); > owner.mergeFieldAccess(this, fCode); > _access = fCode; > - } > + } > + > + public int getAssociationType() { > + return _associationType; > + } > + > + public void setAssociationType(int type) { > + _associationType = type; > + } > + > } > > Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java (original) > +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/MetaDataDefaults.java Fri Sep 18 21:53:47 2009 > @@ -115,13 +115,6 @@ > public boolean isAbstractMappingUniDirectional(OpenJPAConfiguration conf); > > /** > - * Whether the JoinColumn annotation is allowed in conjunction with toMany > - * relation. > - * @since 2.0.0 > - */ > - public boolean isJoinColumnAllowedForToManyRelation(OpenJPAConfiguration conf); > - > - /** > * Whether non-default mapping is allowed. > * @since 2.0.0 > */ > > Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java (original) > +++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/meta/NoneMetaDataFactory.java Fri Sep 18 21:53:47 2009 > @@ -163,10 +163,6 @@ > return false; > } > > - public boolean isJoinColumnAllowedForToManyRelation(OpenJPAConfiguration conf) { > - return false; > - } > - > public boolean isNonDefaultMappingAllowed(OpenJPAConfiguration conf) { > return false; > } > > Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_FK.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_FK.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_FK.java (original) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_FK.java Fri Sep 18 21:53:47 2009 > @@ -22,6 +22,13 @@ > > import javax.persistence.*; > > +/** > + * This is the default bi-directional one-to-many mapping. > + * Foreign key strategy is used. > + * Exception is thrown if @JoinColumn is used in conjunction > + * with @OneToMany. > + * @author faywang > + */ > > @Entity > public class Bi_1ToM_FK { > @@ -32,9 +39,9 @@ > > private String name; > > - @OneToMany(mappedBy="bi1mfk") > - @JoinColumn(name="Bi1MFK_ColA") > - private List entityAs = null; > + @OneToMany(mappedBy="bi1mfk", fetch=FetchType.EAGER) > + //@JoinColumn(name="Bi1MFK_ColC") // should comment out > + private List entityCs = null; > > public long getId() { > return id; > @@ -48,11 +55,27 @@ > this.name = name; > } > > - public List getEntityAs() { > - return entityAs; > + public List getEntityCs() { > + return entityCs; > } > > - public void setEntityAs(List entityAs) { > - this.entityAs = entityAs; > + public void setEntityCs(List entityCs) { > + this.entityCs = entityCs; > + } > + > + public int hashCode() { > + return name.hashCode(); > + } > + > + public boolean equals(Object o) { > + if (!(o instanceof Bi_1ToM_FK)) return false; > + Bi_1ToM_FK b = (Bi_1ToM_FK)o; > + if (!b.name.equals(name)) return false; > + if (b.entityCs.size() != entityCs.size()) return false; > + if (b.entityCs.size() == 1) { > + if (!b.entityCs.get(0).getName().equals(entityCs.get(0).getName())) > + return false; > + } > + return true; > } > } > > Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_JT.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_JT.java?rev=816795&view=auto > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_JT.java (added) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_JT.java Fri Sep 18 21:53:47 2009 > @@ -0,0 +1,81 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.openjpa.persistence.compat; > + > +import java.util.List; > + > +import javax.persistence.*; > + > + > + > +@Entity > +public class Bi_1ToM_JT { > + > + @Id > + @GeneratedValue > + private long id; > + > + private String name; > + > + @OneToMany(mappedBy="bi1mjt", fetch=FetchType.EAGER) > + @JoinTable( > + name="Bi1MJT_C", > + joinColumns= > + @JoinColumn(name="C_ID", referencedColumnName="ID"), > + inverseJoinColumns= > + @JoinColumn(name="Bi1MJT_ID", referencedColumnName="ID") > + ) > + private List entityCs = null; > + > + public long getId() { > + return id; > + } > + > + public String getName() { > + return name; > + } > + > + public void setName(String name) { > + this.name = name; > + } > + > + public List getEntityCs() { > + return entityCs; > + } > + > + public void setEntityCs(List entityCs) { > + this.entityCs = entityCs; > + } > + > + public int hashCode() { > + return name.hashCode(); > + } > + > + public boolean equals(Object o) { > + if (!(o instanceof Bi_1ToM_JT)) return false; > + Bi_1ToM_JT b = (Bi_1ToM_JT)o; > + if (!b.name.equals(name)) return false; > + if (b.entityCs.size() != entityCs.size()) return false; > + if (b.entityCs.size() == 1) { > + if (!b.entityCs.get(0).getName().equals(entityCs.get(0).getName())) > + return false; > + } > + return true; > + } > +} > > Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Bi_1ToM_JT.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC.java (original) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC.java Fri Sep 18 21:53:47 2009 > @@ -21,11 +21,10 @@ > import javax.persistence.Entity; > import javax.persistence.GeneratedValue; > import javax.persistence.Id; > -import javax.persistence.ManyToOne; > import javax.persistence.Table; > > @Entity > -@Table(name="JnCol_C") > +@Table(name="Compact_C") > public class EntityC { > > @Id > @@ -34,9 +33,6 @@ > > private String name; > > - @ManyToOne > - Bi_1ToM_FK bi1mfk; > - > public long getId() { > return id; > } > @@ -48,12 +44,4 @@ > public void setName(String name) { > this.name = name; > } > - > - public void setBi1mfk(Bi_1ToM_FK bi1mfk) { > - this.bi1mfk = bi1mfk; > - } > - > - public Bi_1ToM_FK getBi1mfk() { > - return bi1mfk; > - } > } > > Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MFK.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MFK.java?rev=816795&view=auto > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MFK.java (added) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MFK.java Fri Sep 18 21:53:47 2009 > @@ -0,0 +1,56 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.openjpa.persistence.compat; > + > + > +import javax.persistence.*; > + > +@Entity > +public class EntityC_B1MFK { > + > + @Id > + @GeneratedValue > + private long id; > + > + private String name; > + > + @ManyToOne > + Bi_1ToM_FK bi1mfk; > + > + public long getId() { > + return id; > + } > + > + public String getName() { > + return name; > + } > + > + public void setName(String name) { > + this.name = name; > + } > + > + public void setBi1mfk(Bi_1ToM_FK bi1mfk) { > + this.bi1mfk = bi1mfk; > + } > + > + public Bi_1ToM_FK getBi1mfk() { > + return bi1mfk; > + } > + > +} > > Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MFK.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MJT.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MJT.java?rev=816795&view=auto > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MJT.java (added) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MJT.java Fri Sep 18 21:53:47 2009 > @@ -0,0 +1,55 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.openjpa.persistence.compat; > + > +import javax.persistence.*; > + > +@Entity > +public class EntityC_B1MJT { > + > + @Id > + @GeneratedValue > + private long id; > + > + private String name; > + > + @ManyToOne > + Bi_1ToM_JT bi1mjt; > + > + public long getId() { > + return id; > + } > + > + public String getName() { > + return name; > + } > + > + public void setName(String name) { > + this.name = name; > + } > + > + public void setBi1mjt(Bi_1ToM_JT bi1mjt) { > + this.bi1mjt = bi1mjt; > + } > + > + public Bi_1ToM_JT getBi1mjt() { > + return bi1mjt; > + } > + > +} > > Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_B1MJT.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Added: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1MFK.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1MFK.java?rev=816795&view=auto > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1MFK.java (added) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1MFK.java Fri Sep 18 21:53:47 2009 > @@ -0,0 +1,45 @@ > +/* > + * Licensed to the Apache Software Foundation (ASF) under one > + * or more contributor license agreements. See the NOTICE file > + * distributed with this work for additional information > + * regarding copyright ownership. The ASF licenses this file > + * to you under the Apache License, Version 2.0 (the > + * "License"); you may not use this file except in compliance > + * with the License. You may obtain a copy of the License at > + * > + * http://www.apache.org/licenses/LICENSE-2.0 > + * > + * Unless required by applicable law or agreed to in writing, > + * software distributed under the License is distributed on an > + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY > + * KIND, either express or implied. See the License for the > + * specific language governing permissions and limitations > + * under the License. > + */ > +package org.apache.openjpa.persistence.compat; > + > + > +import javax.persistence.*; > + > +@Entity > +public class EntityC_U1MFK { > + > + @Id > + @GeneratedValue > + private long id; > + > + private String name; > + > + public long getId() { > + return id; > + } > + > + public String getName() { > + return name; > + } > + > + public void setName(String name) { > + this.name = name; > + } > + > +} > > Propchange: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/EntityC_U1MFK.java > ------------------------------------------------------------------------------ > svn:eol-style = native > > Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java (original) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/TestSpecCompatibilityOptions.java Fri Sep 18 21:53:47 2009 > @@ -19,6 +19,7 @@ > package org.apache.openjpa.persistence.compat; > > import java.util.ArrayList; > +import java.util.Arrays; > import java.util.HashMap; > import java.util.List; > import java.util.Map; > @@ -127,66 +128,252 @@ > } > } > > - /* > - * Per JPA 2.0, JoinColumn annotation is allowed on OneToMany relations. > + /** > + * Per JPA 2.0, the following one-to-many mappings are supported. > + * (1) uni-/OneToMany/foreign key strategy > + * (2) uni-/OneToMany/join table strategy (default) > + * (3) bi-/OneToMany/foreign key strategy (default) > + * (4) bi-/OneToMany/join table strategy > + * The JoinColumn and JoinTable annotations or corresponding XML > + * elements must be used to specify such non-default mappings > + * > + * For (1), the spec provides the following example (Sec 11.1.36): > + * Example 3: Unidirectional One-to-Many association using a foreign > + * key mapping: > + * In Customer class: > + * @OneToMany(orphanRemoval=true) > + * @JoinColumn(name="CUST_ID") // join column is in table for Order > + * public Set getOrders() {return orders;} > + * > + * For (4), Bi-directional One-t-Many association using the join > + * table mapping: > + * In Customer class: > + * @OneToMany(mappedBy="customer") > + * @JoinTable( > + * name="Customer_Orders", > + * joinColumns= > + * @JoinColumn(name="Order_ID", referencedColumnName="ID"), > + * inverseJoinColumns= > + * @JoinColumn(name="Cust_ID", referencedColumnName="ID") > + * ) > + * public Set getOrders() {return orders;} > + * > + * Note that in this scenario, @JoinTable is required. Simply applying @JoinColumn > + * without @JoinTable will result in an exception thrown by openjpa. > + * > */ > - public void testJoinColumnOnToManyRelation() { > + public void testOneToManyRelation() { > List> types = new ArrayList>(); > types.add(EntityC.class); > + types.add(EntityC_B1MFK.class); > + types.add(EntityC_B1MJT.class); > + types.add(EntityC_U1MFK.class); > types.add(Bi_1ToM_FK.class); > + types.add(Bi_1ToM_JT.class); > types.add(Uni_1ToM_FK.class); > types.add(Uni_1ToM_JT.class); > - > OpenJPAEntityManagerFactorySPI emf = createEMF2_0(types); > EntityManager em = emf.createEntityManager(); > - > + > try { > // trigger table creation > em.getTransaction().begin(); > em.getTransaction().commit(); > - em.close(); > - emf.close(); > - if (!SQLSniffer.matches(sql, "CREATE TABLE JnCol_C", "Bi1MFK_ColA")) > - fail("JoinColumn annotation fails to be with OneToMany relation"); > + assertSQLFragnments(sql, "CREATE TABLE Bi1MJT_C", "C_ID", "Bi1MJT_ID"); > + assertSQLFragnments(sql, "CREATE TABLE EntityC_B1MFK", "BI1MFK_ID"); > + assertSQLFragnments(sql, "CREATE TABLE Uni1MJT_C", "Uni1MJT_ID", "C_ID"); > + assertSQLFragnments(sql, "CREATE TABLE EntityC_B1MFK", "BI1MFK_ID"); > + assertSQLFragnments(sql, "CREATE TABLE EntityC_U1MFK", "Uni1MFK_ID"); > + crudUni1MFK(em); > + crudUni1MJT(em); > + crudBi1MFK(em); > + crudBi1MJT(em); > } catch (Exception e) { > - fail("JoinColumn annotation fails to be with OneToMany relation"); > + e.printStackTrace(); > + fail("OneToMany mapping failed with exception message: " + e.getMessage()); > + } finally { > + em.close(); > + emf.close(); > } > } > + > + // non default > + public void crudUni1MFK(EntityManager em) { > + //create > + Uni_1ToM_FK u = new Uni_1ToM_FK(); > + u.setName("uni1mfk"); > + List cs = new ArrayList(); > + EntityC_U1MFK c = new EntityC_U1MFK(); > + c.setName("c"); > + cs.add(c); > + u.setEntityCs(cs); > + em.persist(u); > + em.persist(c); > + em.getTransaction().begin(); > + em.getTransaction().commit(); > + > + //update > + em.getTransaction().begin(); > + cs = u.getEntityCs(); > + u.setName("newName"); > + EntityC_U1MFK c1 = new EntityC_U1MFK(); > + c1.setName("c1"); > + cs.add(c1); > + em.persist(c1); > + em.getTransaction().commit(); > + em.clear(); > + > + //query > + Query q = em.createQuery("SELECT u FROM Uni_1ToM_FK u"); > + Uni_1ToM_FK u1 = (Uni_1ToM_FK)q.getSingleResult(); > + assertEquals(u, u1); > + em.clear(); > + > + //find > + long id = u1.getId(); > + Uni_1ToM_FK u2 = em.find(Uni_1ToM_FK.class, id); > + assertEquals(u, u2); > + > + //remove > + em.getTransaction().begin(); > + em.remove(u2); > + em.getTransaction().commit(); > + em.clear(); > + } > + > + // default > + public void crudUni1MJT(EntityManager em) { > + Uni_1ToM_JT u = new Uni_1ToM_JT(); > + u.setName("uni1mjt"); > + List cs = new ArrayList(); > + EntityC c = new EntityC(); > + c.setName("c"); > + cs.add(c); > + u.setEntityCs(cs); > + em.persist(u); > + em.persist(c); > + em.getTransaction().begin(); > + em.getTransaction().commit(); > + > + //update > + em.getTransaction().begin(); > + cs = u.getEntityCs(); > + u.setName("newName"); > + EntityC c1 = new EntityC(); > + c1.setName("c1"); > + cs.add(c1); > + em.persist(c1); > + em.getTransaction().commit(); > + em.clear(); > + > + //query > + Query q = em.createQuery("SELECT u FROM Uni_1ToM_JT u"); > + Uni_1ToM_JT u1 = (Uni_1ToM_JT)q.getSingleResult(); > + assertEquals(u, u1); > + em.clear(); > + > + //find > + long id = u1.getId(); > + Uni_1ToM_JT u2 = em.find(Uni_1ToM_JT.class, id); > + assertEquals(u, u2); > + > + //remove > + em.getTransaction().begin(); > + em.remove(u2); > + em.getTransaction().commit(); > + em.clear(); > + } > + > + //default > + public void crudBi1MFK(EntityManager em) { > + Bi_1ToM_FK b = new Bi_1ToM_FK(); > + b.setName("bi1mfk"); > + List cs = new ArrayList(); > + EntityC_B1MFK c = new EntityC_B1MFK(); > + c.setName("c"); > + c.setBi1mfk(b); > + cs.add(c); > + b.setEntityCs(cs); > + em.persist(b); > + em.persist(c); > + em.getTransaction().begin(); > + em.getTransaction().commit(); > + > + //update > + em.getTransaction().begin(); > + cs = b.getEntityCs(); > + b.setName("newName"); > + EntityC_B1MFK c1 = new EntityC_B1MFK(); > + c1.setName("c1"); > + cs.add(c1); > + c1.setBi1mfk(b); > + em.persist(c1); > + em.getTransaction().commit(); > + em.clear(); > + > + //query > + Query q = em.createQuery("SELECT u FROM Bi_1ToM_FK u"); > + Bi_1ToM_FK b1 = (Bi_1ToM_FK)q.getSingleResult(); > + assertEquals(b, b1); > + em.clear(); > + > + //find > + long id = b1.getId(); > + Bi_1ToM_FK b2 = em.find(Bi_1ToM_FK.class, id); > + assertEquals(b, b2); > + > + //remove > + em.getTransaction().begin(); > + em.remove(b2); > + em.getTransaction().commit(); > + em.clear(); > + } > > - /* > - * Per JPA 2.0, non-default mapping of uni-directional OneToMany using > - * foreign key strategy is allowed. > - */ > - public void testNonDefaultUniOneToManyRelationUsingForeignKey() { > - List> types = new ArrayList>(); > - types.add(EntityC.class); > - types.add(Bi_1ToM_FK.class); > - types.add(Uni_1ToM_FK.class); > - types.add(Uni_1ToM_JT.class); > - OpenJPAEntityManagerFactorySPI emf = createEMF2_0(types); > - EntityManager em = emf.createEntityManager(); > + // non default > + public void crudBi1MJT(EntityManager em) { > + Bi_1ToM_JT b = new Bi_1ToM_JT(); > + b.setName("bi1mfk"); > + List cs = new ArrayList(); > + EntityC_B1MJT c = new EntityC_B1MJT(); > + c.setName("c"); > + c.setBi1mjt(b); > + cs.add(c); > + b.setEntityCs(cs); > + em.persist(b); > + em.persist(c); > + em.getTransaction().begin(); > + em.getTransaction().commit(); > + > + //update > + em.getTransaction().begin(); > + cs = b.getEntityCs(); > + b.setName("newName"); > + EntityC_B1MJT c1 = new EntityC_B1MJT(); > + c1.setName("c1"); > + cs.add(c1); > + c1.setBi1mjt(b); > + em.persist(c1); > + em.getTransaction().commit(); > + em.clear(); > > - try { > - // trigger table creation > - Uni_1ToM_FK uni1mfk = new Uni_1ToM_FK(); > - uni1mfk.setName("test"); > - EntityC c = new EntityC(); > - c.setName("c"); > - List cs = new ArrayList(); > - cs.add(c); > - uni1mfk.setEntityAs(cs); > - em.persist(uni1mfk); > - em.persist(c); > - em.getTransaction().begin(); > - em.getTransaction().commit(); > - em.close(); > - emf.close(); > - if (!SQLSniffer.matches(sql, "CREATE TABLE JnCol_C", "Uni1MFK_ColA")) > - fail("JoinColumn annotation fails to be with OneToMany relation"); > - } catch (Exception e) { > - fail("Non-default uni-directional OneToMany Using foreign key fails"); > - } > + //query > + Query q = em.createQuery("SELECT u FROM Bi_1ToM_JT u"); > + Bi_1ToM_JT b1 = (Bi_1ToM_JT)q.getSingleResult(); > + assertEquals(b, b1); > + em.clear(); > + > + //find > + long id = b1.getId(); > + Bi_1ToM_JT b2 = em.find(Bi_1ToM_JT.class, id); > + assertEquals(b, b2); > + > + //remove > + em.getTransaction().begin(); > + em.remove(b2); > + em.getTransaction().commit(); > + em.clear(); > } > + > > private OpenJPAEntityManagerFactorySPI createEMF2_0(List> types) { > Map map = new HashMap(); > @@ -213,6 +400,21 @@ > "persistence_2_0.xml", map); > } > > + void assertSQLFragnments(List list, String... keys) { > + if (SQLSniffer.matches(list, keys)) > + return; > + fail("None of the following " + sql.size() + " SQL \r\n" + > + toString(sql) + "\r\n contains all keys \r\n" > + + toString(Arrays.asList(keys))); > + } > + > + public String toString(List list) { > + StringBuffer buf = new StringBuffer(); > + for (String s : list) > + buf.append(s).append("\r\n"); > + return buf.toString(); > + } > + > public class Listener extends AbstractJDBCListener { > @Override > public void beforeExecuteStatement(JDBCEvent event) { > > Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_FK.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_FK.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_FK.java (original) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_FK.java Fri Sep 18 21:53:47 2009 > @@ -22,13 +22,13 @@ > > import javax.persistence.*; > > -//non-default mapping > -//Sec 11.1.36, Example 3: > -// Unidirectional One-to-Many association using a foreign key mapping > -// In Customer class: > -// @OneToMany(orphanRemoval=true) > -// @JoinColumn(name="CUST_ID") // join column is in table for Order > -// public Set getOrders() {return orders;} > +/** > + * This is the non-default uni-directional one-to-many mapping. > + * Foreign key strategy is used. > + * @JoinColumn is required for this strategy (see Spec 11.1.36, Ex 3) > + * with @OneToMany. > + * @author faywang > + */ > > @Entity > public class Uni_1ToM_FK { > @@ -39,9 +39,9 @@ > > private String name; > > - @OneToMany > - @JoinColumn(name="Uni1MFK_ColA") > - private List entityAs = null; > + @OneToMany(fetch=FetchType.EAGER) > + @JoinColumn(name="Uni1MFK_ID") > + private List entityCs = null; > > public long getId() { > return id; > @@ -55,11 +55,27 @@ > this.name = name; > } > > - public List getEntityAs() { > - return entityAs; > + public List getEntityCs() { > + return entityCs; > } > > - public void setEntityAs(List entityAs) { > - this.entityAs = entityAs; > + public void setEntityCs(List entityCs) { > + this.entityCs = entityCs; > + } > + > + public int hashCode() { > + return name.hashCode(); > + } > + > + public boolean equals(Object o) { > + if (!(o instanceof Uni_1ToM_FK)) return false; > + Uni_1ToM_FK b = (Uni_1ToM_FK)o; > + if (!b.name.equals(name)) return false; > + if (b.entityCs.size() != entityCs.size()) return false; > + if (b.entityCs.size() == 1) { > + if (!b.entityCs.get(0).getName().equals(entityCs.get(0).getName())) > + return false; > + } > + return true; > } > } > > Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_JT.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_JT.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_JT.java (original) > +++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/compat/Uni_1ToM_JT.java Fri Sep 18 21:53:47 2009 > @@ -22,6 +22,12 @@ > > import javax.persistence.*; > > +/** > + * This is the default uni-directional one-to-many mapping. > + * Join table strategy is used. > + * > + * @author faywang > + */ > > @Entity > public class Uni_1ToM_JT { > @@ -32,15 +38,15 @@ > > private String name; > > - @OneToMany > + @OneToMany(fetch=FetchType.EAGER) > @JoinTable( > - name="Uni_1TOM_JT_C", > + name="Uni1MJT_C", > joinColumns= > @JoinColumn(name="Uni1MJT_ID", referencedColumnName="ID"), > inverseJoinColumns= > @JoinColumn(name="C_ID", referencedColumnName="ID") > ) > - private List entityAs = null; > + private List entityCs = null; > > public long getId() { > return id; > @@ -54,11 +60,27 @@ > this.name = name; > } > > - public List getEntityAs() { > - return entityAs; > + public List getEntityCs() { > + return entityCs; > } > > - public void setEntityAs(List entityAs) { > - this.entityAs = entityAs; > + public void setEntityCs(List entityAs) { > + this.entityCs = entityAs; > + } > + > + public int hashCode() { > + return name.hashCode(); > + } > + > + public boolean equals(Object o) { > + if (!(o instanceof Uni_1ToM_JT)) return false; > + Uni_1ToM_JT b = (Uni_1ToM_JT)o; > + if (!b.name.equals(name)) return false; > + if (b.entityCs.size() != entityCs.size()) return false; > + if (b.entityCs.size() == 1) { > + if (!b.entityCs.get(0).getName().equals(entityCs.get(0).getName())) > + return false; > + } > + return true; > } > } > > Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java (original) > +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/AnnotationPersistenceMetaDataParser.java Fri Sep 18 21:53:47 2009 > @@ -1386,6 +1386,7 @@ > if (anno.targetEntity() != void.class) > fmd.setTypeOverride(anno.targetEntity()); > setCascades(fmd, anno.cascade()); > + fmd.setAssociationType(FieldMetaData.MANY_TO_ONE); > } > > /** > @@ -1410,6 +1411,7 @@ > fmd.setTypeOverride(anno.targetEntity()); > setCascades(fmd, anno.cascade()); > setOrphanRemoval(fmd, anno.orphanRemoval()); > + fmd.setAssociationType(FieldMetaData.ONE_TO_ONE); > } > > /** > @@ -1450,6 +1452,7 @@ > fmd.getElement().setDeclaredType(anno.targetEntity()); > setCascades(fmd.getElement(), anno.cascade()); > setOrphanRemoval(fmd.getElement(), anno.orphanRemoval()); > + fmd.setAssociationType(FieldMetaData.ONE_TO_MANY); > } > > /** > @@ -1474,6 +1477,7 @@ > if (anno.targetEntity() != void.class) > fmd.getElement().setDeclaredType(anno.targetEntity()); > setCascades(fmd.getElement(), anno.cascade()); > + fmd.setAssociationType(FieldMetaData.MANY_TO_MANY); > } > > /** > > Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java (original) > +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceMetaDataDefaults.java Fri Sep 18 21:53:47 2009 > @@ -132,7 +132,6 @@ > protected GetterFilter getterFilter = new GetterFilter(); > protected SetterFilter setterFilter = new SetterFilter(); > private Boolean _isAbstractMappingUniDirectional = null; > - private Boolean _isJoinColumnAllowedForToManyRelation = null; > private Boolean _isNonDefaultMappingAllowed = null; > > public PersistenceMetaDataDefaults() { > @@ -875,17 +874,6 @@ > _isAbstractMappingUniDirectional = conf.getCompatibilityInstance().isAbstractMappingUniDirectional(); > } > > - public boolean isJoinColumnAllowedForToManyRelation(OpenJPAConfiguration conf) { > - if (_isJoinColumnAllowedForToManyRelation == null) > - setJoinColumnAllowedForToManyRelation(conf); > - return _isJoinColumnAllowedForToManyRelation; > - } > - > - public void setJoinColumnAllowedForToManyRelation(OpenJPAConfiguration conf) { > - _isJoinColumnAllowedForToManyRelation = conf.getCompatibilityInstance(). > - isJoinColumnAllowedForToManyRelation(); > - } > - > public boolean isNonDefaultMappingAllowed(OpenJPAConfiguration conf) { > if (_isNonDefaultMappingAllowed == null) > setNonDefaultMappingAllowed(conf); > > Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java > URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java?rev=816795&r1=816794&r2=816795&view=diff > ============================================================================== > --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java (original) > +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProductDerivation.java Fri Sep 18 21:53:47 2009 > @@ -186,7 +186,6 @@ > conf.validationMode.set(String.valueOf(ValidationMode.NONE)); > } else { > compatibility.setAbstractMappingUniDirectional(true); > - compatibility.setJoinColumnAllowedForToManyRelation(true); > compatibility.setNonDefaultMappingAllowed(true); > } > return true; > > >