gpt4 book ai didi

java - 外键作为 OpenJPA 中复合主键和 ManyToOne 关系的一部分

转载 作者:行者123 更新时间:2023-12-01 12:42:06 25 4
gpt4 key购买 nike

我想使用 OpenJPA 2.3 创建简单的数据库。

TableA:
- f_id PK
- item PK
- release PK
- b_id PK
- field1
- field2

TableB:
- id PK
- name
- date

哪里b_idTableA引用idTableB (许多 TableA 行到一个 TableB 行)。 b_id是整个复合主键的一部分。

表A类:

@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主键类:

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 类:

 @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
}

当我尝试坚持TableB对象异常已抛出:

org.apache.openjpa.persistence.ArgumentException: Attempt to map "model.TableA.tableB" failed: the owning entity is not mapped.

如何解决这个问题?

我的理论/解释:看起来,当我尝试坚持时TableB对象 rows 的每个元素必须坚持。但在 TableA有一个字段private TableB tableB (尚未持久化),因此我们陷入无限递归;)。

编辑:

完整跟踪(更改前):

<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)

更改后的完整跟踪(当我在 tableB 上更改 TableA_PKlong 的类型时):

<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

更改后的完整跟踪(当我更改 tableBTableA_PKLong 的类型,以及 idTableBLong 的类型时):

<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

在 @Gas 回答后进行编辑

我就是按照你说的做的。但我在坚持整个 TableB 时遇到问题对象,我的测试类:

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();
}

我有异常(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
为什么?我想它会坚持什么 tb首先,然后是 rows 中的每个元素将知道获得的TableB.id(感谢 tableB类中的 TableA字段)。这是什么问题?

如果我在持久之前在测试中添加两行:

ta1.setTableB(tb);
ta2.setTableB(tb);

将抛出此异常:

Caused by: java.lang.ClassCastException: org.model.TableB cannot be cast to java.lang.Number

(我需要自己在tableB中设置TableA字段吗?)

如何坚持TableB对象?

编辑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>

最佳答案

这对我来说适用于以下代码。更改了TableA_PK中的长tableB和TableA中的@JoinColumn。

表格

@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;

表A_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

表B

@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

评论后更新
不幸的是,派生键不支持生成的值,并且在插入项目之前它是未知的。因此,您需要首先保留 tableB 项目,然后添加行。检查以下代码:

    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

关于java - 外键作为 OpenJPA 中复合主键和 ManyToOne 关系的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25003365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com