Reputation: 125
I want to create simple database with OpenJPA 2.3.
TableA:
- f_id PK
- item PK
- release PK
- b_id PK
- field1
- field2
TableB:
- id PK
- name
- date
Where b_id
in TableA
references to id
in TableB
(MANY TableA
rows to ONE TableB
row). b_id
is a part of entire composite primary key.
TableA class:
@Entity
@IdClass(TableA_PK.class)
public class TableA implements Serializable {
@Id
private int fId;
@Id
private String item;
@Id
private String release;
@Id
@ManyToOne
@PrimaryKeyJoinColumn(name="b_id", referencedColumnName="id")
private TableB tableB;
@Column
private String field1;
@Column
private String field2;
public TableA() {}
//getters, setters, equals, hashCode methods
}
TableA primary key class:
public class TableA_PK implements Serializable {
private int fId;
private String item;
private String release;
private TableB tableB;
public TableA_PK() {}
//getters, setters, equals, hashCode methods
}
TableB class:
@Entity
public class TableB implements Serializable {
@Id
@GeneratedValue
private long id;
@Column
private String name;
@Column
private Date date;
@OneToMany(mappedBy="tableB", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
private List<TableA> rows;
public TableB() {}
//getters, setters, equals, hashCode methods
}
When I try to persist TableB
object Exception had been thrown:
org.apache.openjpa.persistence.ArgumentException: Attempt to map "model.TableA.tableB" failed: the owning entity is not mapped.
How to fix this?
My theory/explanation: It looks like, when I try to persist TableB
object every element of rows
must be persisted. But in TableA
there is a field private TableB tableB
(which is not persisted yet), so we fall into infinity recursion ;).
EDIT:
Full Trace (before changes):
<openjpa-2.3.0-r422266:1540826 fatal user error> org.apache.openjpa.persistence.ArgumentException: Errors encountered while resolving metadata. See nested exceptions for details.
at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:675)
at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:418)
at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:389)
at org.apache.openjpa.jdbc.meta.MappingRepository.getMapping(MappingRepository.java:354)
at org.apache.openjpa.jdbc.meta.MappingTool.getMapping(MappingTool.java:682)
at org.apache.openjpa.jdbc.meta.MappingTool.buildSchema(MappingTool.java:754)
at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:652)
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:154)
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:164)
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newBrokerImpl(JDBCBrokerFactory.java:122)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:209)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:155)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:226)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:153)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:59)
at org.JpaTest.test(JpaTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: <openjpa-2.3.0-r422266:1540826 fatal user error> org.apache.openjpa.persistence.ArgumentException: The id class specified by type "class org.model.TableA" does not match the primary key fields of the class. Make sure your identity class has the same primary keys as your persistent type, including pk field types. Mismatched property: "tableB"
at org.apache.openjpa.meta.ClassMetaData.validateAppIdClassPKs(ClassMetaData.java:2225)
at org.apache.openjpa.meta.ClassMetaData.validateAppIdClass(ClassMetaData.java:2099)
at org.apache.openjpa.meta.ClassMetaData.validateIdentity(ClassMetaData.java:2035)
at org.apache.openjpa.meta.ClassMetaData.validateMeta(ClassMetaData.java:1947)
at org.apache.openjpa.meta.ClassMetaData.resolve(ClassMetaData.java:1808)
at org.apache.openjpa.meta.MetaDataRepository.processBuffer(MetaDataRepository.java:829)
at org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepository.java:726)
at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:650)
... 38 more
NestedThrowables:
<openjpa-2.3.0-r422266:1540826 fatal user error> org.apache.openjpa.persistence.ArgumentException: Attempt to map "org.model.TableA.tableB" failed: the owning entity is not mapped.
at org.apache.openjpa.jdbc.meta.MappingInfo.assertTable(MappingInfo.java:628)
at org.apache.openjpa.jdbc.meta.MappingInfo.createForeignKey(MappingInfo.java:1080)
at org.apache.openjpa.jdbc.meta.ValueMappingInfo.getTypeJoin(ValueMappingInfo.java:115)
at org.apache.openjpa.jdbc.meta.ValueMappingInfo.getTypeJoin(ValueMappingInfo.java:92)
at org.apache.openjpa.jdbc.meta.strats.RelationFieldStrategy.map(RelationFieldStrategy.java:166)
at org.apache.openjpa.jdbc.meta.FieldMapping.setStrategy(FieldMapping.java:146)
at org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:82)
at org.apache.openjpa.jdbc.meta.FieldMapping.resolveMapping(FieldMapping.java:496)
at org.apache.openjpa.jdbc.meta.FieldMapping.resolve(FieldMapping.java:461)
at org.apache.openjpa.jdbc.meta.strats.RelationToManyInverseKeyFieldStrategy.map(RelationToManyInverseKeyFieldStrategy.java:135)
at org.apache.openjpa.jdbc.meta.strats.RelationCollectionInverseKeyFieldStrategy.map(RelationCollectionInverseKeyFieldStrategy.java:94)
at org.apache.openjpa.jdbc.meta.FieldMapping.setStrategy(FieldMapping.java:146)
at org.apache.openjpa.jdbc.meta.RuntimeStrategyInstaller.installStrategy(RuntimeStrategyInstaller.java:82)
at org.apache.openjpa.jdbc.meta.FieldMapping.resolveMapping(FieldMapping.java:496)
at org.apache.openjpa.jdbc.meta.FieldMapping.resolve(FieldMapping.java:461)
at org.apache.openjpa.jdbc.meta.ClassMapping.resolveMapping(ClassMapping.java:854)
at org.apache.openjpa.meta.ClassMetaData.resolve(ClassMetaData.java:1811)
at org.apache.openjpa.meta.MetaDataRepository.processBuffer(MetaDataRepository.java:829)
at org.apache.openjpa.meta.MetaDataRepository.resolveMapping(MetaDataRepository.java:784)
at org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.java:664)
at org.apache.openjpa.meta.MetaDataRepository.getMetaDataInternal(MetaDataRepository.java:418)
at org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepository.java:389)
at org.apache.openjpa.jdbc.meta.MappingRepository.getMapping(MappingRepository.java:354)
at org.apache.openjpa.jdbc.meta.MappingTool.getMapping(MappingTool.java:682)
at org.apache.openjpa.jdbc.meta.MappingTool.buildSchema(MappingTool.java:754)
at org.apache.openjpa.jdbc.meta.MappingTool.run(MappingTool.java:652)
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:154)
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.synchronizeMappings(JDBCBrokerFactory.java:164)
at org.apache.openjpa.jdbc.kernel.JDBCBrokerFactory.newBrokerImpl(JDBCBrokerFactory.java:122)
at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:209)
at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:155)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:226)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:153)
at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:59)
at org.JpaTest.test(JpaTest.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Full Trace, after changes (when I changed type of tableB
in TableA_PK
on long
):
<openjpa-2.3.0-r422266:1540826 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: org.model.TableB cannot be cast to java.lang.Number
at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2526)
at org.apache.openjpa.kernel.SingleFieldManager.persist(SingleFieldManager.java:279)
at org.apache.openjpa.kernel.StateManagerImpl.cascadePersist(StateManagerImpl.java:3081)
at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2703)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2604)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2587)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2491)
at org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1077)
at org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:716)
at org.JpaTest.test(JpaTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassCastException: org.model.TableB cannot be cast to java.lang.Number
at org.apache.openjpa.util.ApplicationIds$PrimaryKeyFieldManager.fetchLongField(ApplicationIds.java:669)
at org.apache.openjpa.enhance.org$model$TableA$pcsubclass.pcCopyKeyFieldsToObjectId(Unknown Source)
at org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:169)
at org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:224)
at org.apache.openjpa.enhance.ReflectingPersistenceCapable.pcNewObjectIdInstance(ReflectingPersistenceCapable.java:277)
at org.apache.openjpa.util.ApplicationIds.create(ApplicationIds.java:427)
at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2675)
at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2521)
... 32 more
Full Trace, after changes (when I changed type of tableB
in TableA_PK
on Long
, and type of id
in TableB
on Long
):
<openjpa-2.3.0-r422266:1540826 nonfatal general error> org.apache.openjpa.persistence.PersistenceException: Can not set java.lang.Long field org.model.TableA_PK.tableB to org.model.TableB
at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2526)
at org.apache.openjpa.kernel.SingleFieldManager.persist(SingleFieldManager.java:279)
at org.apache.openjpa.kernel.StateManagerImpl.cascadePersist(StateManagerImpl.java:3081)
at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2703)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2604)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2587)
at org.apache.openjpa.kernel.BrokerImpl.persist(BrokerImpl.java:2491)
at org.apache.openjpa.kernel.DelegatingBroker.persist(DelegatingBroker.java:1077)
at org.apache.openjpa.persistence.EntityManagerImpl.persist(EntityManagerImpl.java:716)
at org.JpaTest.test(JpaTest.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field org.model.TableA_PK.tableB to org.model.TableB
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.apache.openjpa.enhance.Reflection.set(Reflection.java:538)
at org.apache.openjpa.enhance.org$model$RowData$pcsubclass.pcCopyKeyFieldsToObjectId(Unknown Source)
at org.apache.openjpa.enhance.PCRegistry.copyKeyFieldsToObjectId(PCRegistry.java:169)
at org.apache.openjpa.util.ApplicationIds.fromPKValues(ApplicationIds.java:224)
at org.apache.openjpa.enhance.ReflectingPersistenceCapable.pcNewObjectIdInstance(ReflectingPersistenceCapable.java:277)
at org.apache.openjpa.util.ApplicationIds.create(ApplicationIds.java:427)
at org.apache.openjpa.kernel.BrokerImpl.persistInternal(BrokerImpl.java:2675)
at org.apache.openjpa.kernel.BrokerImpl.persistAll(BrokerImpl.java:2521)
... 32 more
Caused by: java.lang.IllegalArgumentException: Error while setting value org.model.TableB@982c7dfd of class org.model.TableB on field private java.lang.Long org.model.TableA_PK.tableB of instance org.model.TableA_PK@e426b053 by reflection.
at org.apache.openjpa.enhance.Reflection.wrapReflectionException(Reflection.java:334)
at org.apache.openjpa.enhance.Reflection.set(Reflection.java:540)
... 39 more
EDIT AFTER @Gas ANSWER
I did just like you said. But I have problem with persist entire TableB
object, my test class:
public class JpaTest {
@Test
public void test() {
TableB tb = new TableB();
tb.setName("testing");
tb.setDate(new Date());
TableA ta1 = new TableA();
ta1.setFId(1);
ta1.setItem("item1");
ta1.setRelease("release1");
ta1.setField1("f1");
ta1.setField2("f2");
TableA ta2 = new TableA();
ta2.setFId(2);
ta2.setItem("item2");
ta2.setRelease("release2");
ta2.setField1("F1");
ta2.setField2("F2");
List<TableA> alist = new ArrayList<TableA>();
alist.add(ta1);
alist.add(ta2);
tb.setRows(alist);
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("rd-jpa");
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction userTransaction = em.getTransaction();
userTransaction.begin();
em.persist(tb);
userTransaction.commit();
em.clear();
em.close();
}
I have Exception:
org.apache.openjpa.persistence.RollbackException: The transaction has been rolled back. See the nested exceptions for details on the errors that occurred.
(...)
Caused by: org.apache.openjpa.lib.jdbc.ReportingSQLException: ERROR: null value in column "b_id" violates not-null constraint
Why? I thought what it'll persist tb
first, and then every element in rows
will have know about obtained TableB.id (thanks to tableB
field in TableA
class). What's wrong with this?
If I add two lines in Test before persist:
ta1.setTableB(tb);
ta2.setTableB(tb);
this Exception will be throw:
Caused by: java.lang.ClassCastException: org.model.TableB cannot be cast to java.lang.Number
(Do I need set tableB
field in TableA
by myself?)
How to persist TableB
object?
EDIT 3: persistence.xml
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="rd-jpa" transaction-type="RESOURCE_LOCAL">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<class>org.model.TableA</class>
<class>org.model.TableB</class>
<properties>
<property name="openjpa.ConnectionURL"
value="jdbc:postgresql://localhost:5432/mydb" />
<property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver" />
<property name="openjpa.ConnectionUserName" value="postgres" />
<property name="openjpa.ConnectionPassword" value="postgres" />
<property name="openjpa.DynamicEnhancementAgent" value="true" />
<property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
</properties>
</persistence-unit>
</persistence>
Upvotes: 0
Views: 1442
Reputation: 18020
This works for me for the following code. Changed the long tableB in TableA_PK and @JoinColumn in TableA.
TABLEA
@Entity
@IdClass(TableA_PK.class)
public class TableA implements Serializable {
@Id
private int fId;
@Id
private String item;
@Id
private String release;
@Id
@ManyToOne
@JoinColumn(name="b_id")
private TableB tableB;
@Column
private String field1;
@Column
private String field2;
TABLEA_PK
public class TableA_PK implements Serializable {
private int fId;
private String item;
private String release;
private long tableB;
public TableA_PK() {}
//getters, setters, equals, hashCode methods
TABLEB
@Entity
public class TableB implements Serializable {
@Id
@GeneratedValue
private long id;
@Column
private String name;
@Column
private Date date;
@OneToMany(mappedBy="tableB")
private List<TableA> rows;
public TableB() {}
//getters, setters, equals, hashCode methods
UPDATE after comment
Unfortunately generated value is not supported for derived keys and its not known before item is inserted. So you need first to persist tableB item and then add rows.
Check the following code:
TableB tableb = new TableB();
tableb.setDate(new Date());
tableb.setName("tableb2");
em.persist(tableb); // fills tableb id
System.out.println(tableb);
TableA tableA = new TableA();
tableA.setfId((int) new Date().getTime());
tableA.setField1("field1");
tableA.setField2("field2");
tableA.setItem("item2");
tableA.setRelease("1");
tableA.setTableB(tableb);
ArrayList<TableA> rows = new ArrayList<TableA>();
rows.add(tableA);
tableb.setRows(rows);
em.merge(tableb); // inserts tablea objects, you could also just persist tableA items
Upvotes: 1