JPA 删除 Many-to-One 关系中的 "one"
JPA Delete the "one" in a Many-to-One relation
我有这两个 classes:
@Entity
public class Tag {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
private List<TagValue> values;
private String name;
}
@Entity
public class TagValue {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@ManyToOne
private Tag parent;
}
这两个是 parent child 关系,child 知道它是 parent。
当我尝试删除 parent 而 child 仍在引用它时,我的问题就开始了。 Eclipse Link 告诉我我违反了外键约束,因为 child (TagValue) 仍在引用它。当 child 仍然引用它时,我该如何更改我当前的方法才能删除 parent?
最后,当我删除 parent 时,如何告诉 JPA 删除所有引用 parent 的 child?它必须像这样工作。我知道 parent 知道它是 children 使用列表会更容易,但这不是我所追求的。
我玩过级联等等,但我似乎不明白。
编辑:
所以有人告诉我,它应该已经可以使用我的代码了。既然没有,这里是失败的用例和错误的堆栈跟踪。
TagValue value = new TagValue();
value.setName("Testvalue");
Tag tag = new Tag();
tag.setName("Testtag");
value.setParent(tag);
Database.addTag(tag);
Database.addTagValue(value);
Database.removeTag(tag);
数据库class方法定义如下:
public static void addTag(final Tag tag) throws Exception {
manager.getTransaction().begin();
manager.persist(tag);
manager.getTransaction().commit();
}
public static void addTagValue(final TagValue value) throws Exception {
manager.getTransaction().begin();
manager.persist(value);
manager.getTransaction().commit();
}
public static void removeTag(final Tag tag) throws Exception {
manager.getTransaction().begin();
manager.remove(tag);
manager.getTransaction().commit();
}
堆栈跟踪:
注:Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“
表示
(id)=(1)
键仍然在 table 标记值中被引用。
[EL Warning]: 2015-02-24 11:12:43.785--UnitOfWork(390138887)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
Error Code: 0
Call: DELETE FROM TAG WHERE (ID = ?)
bind => [1 parameter bound]
Query: DeleteObjectQuery(Tag(id=1, values=[], name=Testtag))
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
Error Code: 0
Call: DELETE FROM TAG WHERE (ID = ?)
bind => [1 parameter bound]
Query: DeleteObjectQuery(Tag(id=1, values=[], name=Testtag))
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
at de.yabue.baka.YabueCentral.Persistence.Database.removeTag(Database.java:256)
at de.yabue.baka.YabueCentral.Persistence.DatabaseTest.testPersistence(DatabaseTest.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:74)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:673)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:846)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1170)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.runWorkers(TestRunner.java:1147)
at org.testng.TestRunner.privateRun(TestRunner.java:749)
at org.testng.TestRunner.run(TestRunner.java:600)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:317)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:312)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:274)
at org.testng.SuiteRunner.run(SuiteRunner.java:223)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1039)
at org.testng.TestNG.runSuitesLocally(TestNG.java:964)
at org.testng.TestNG.run(TestNG.java:900)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:110)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:205)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:174)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
Error Code: 0
Call: DELETE FROM TAG WHERE (ID = ?)
bind => [1 parameter bound]
Query: DeleteObjectQuery(Tag(id=1, values=[], name=Testtag))
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1611)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:898)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:210)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:104)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeDatabaseQuery(DeleteObjectQuery.java:218)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:119)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1737)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:336)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:285)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1444)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
... 33 more
Caused by: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)
... 59 more
我也试图在删除之前先从数据库中获取要删除的标签,但是返回的实例在values
列表中没有任何项目。所以我最后的猜测是,我必须自己填写列表 values
?
就像我最后的建议一样,我必须自己填写 parent 的列表。所以现在没有更多的错误了。
我改变了这个方法:
public static void addTagValue(final TagValue value) throws Exception {
manager.getTransaction().begin();
manager.persist(value);
manager.getTransaction().commit();
}
至:
public static void addTagValue(final TagValue value) throws Exception {
manager.getTransaction().begin();
value.getParent().getValues().add(value);
manager.persist(value);
manager.getTransaction().commit();
}
这就是我之前没有调查的原因:
首先,我不知何故认为 mappedBy
会自动完成这项工作。
此外,我使用 lombok 生成我的 setter 和 getter,并通过 @Data
注释这样做。此注释生成了所有 setter 和 getter,还生成了 toString()
和 hashCode()
方法。当我将一个项目添加到 values
列表时,hashCode()
方法产生了一个 Whosebug,我必须先解决这个问题。
我有这两个 classes:
@Entity
public class Tag {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "parent")
private List<TagValue> values;
private String name;
}
@Entity
public class TagValue {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@ManyToOne
private Tag parent;
}
这两个是 parent child 关系,child 知道它是 parent。 当我尝试删除 parent 而 child 仍在引用它时,我的问题就开始了。 Eclipse Link 告诉我我违反了外键约束,因为 child (TagValue) 仍在引用它。当 child 仍然引用它时,我该如何更改我当前的方法才能删除 parent?
最后,当我删除 parent 时,如何告诉 JPA 删除所有引用 parent 的 child?它必须像这样工作。我知道 parent 知道它是 children 使用列表会更容易,但这不是我所追求的。 我玩过级联等等,但我似乎不明白。
编辑:
所以有人告诉我,它应该已经可以使用我的代码了。既然没有,这里是失败的用例和错误的堆栈跟踪。
TagValue value = new TagValue();
value.setName("Testvalue");
Tag tag = new Tag();
tag.setName("Testtag");
value.setParent(tag);
Database.addTag(tag);
Database.addTagValue(value);
Database.removeTag(tag);
数据库class方法定义如下:
public static void addTag(final Tag tag) throws Exception {
manager.getTransaction().begin();
manager.persist(tag);
manager.getTransaction().commit();
}
public static void addTagValue(final TagValue value) throws Exception {
manager.getTransaction().begin();
manager.persist(value);
manager.getTransaction().commit();
}
public static void removeTag(final Tag tag) throws Exception {
manager.getTransaction().begin();
manager.remove(tag);
manager.getTransaction().commit();
}
堆栈跟踪:
注:Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“
表示
(id)=(1)
键仍然在 table 标记值中被引用。
[EL Warning]: 2015-02-24 11:12:43.785--UnitOfWork(390138887)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
Error Code: 0
Call: DELETE FROM TAG WHERE (ID = ?)
bind => [1 parameter bound]
Query: DeleteObjectQuery(Tag(id=1, values=[], name=Testtag))
javax.persistence.RollbackException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
Error Code: 0
Call: DELETE FROM TAG WHERE (ID = ?)
bind => [1 parameter bound]
Query: DeleteObjectQuery(Tag(id=1, values=[], name=Testtag))
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:157)
at de.yabue.baka.YabueCentral.Persistence.Database.removeTag(Database.java:256)
at de.yabue.baka.YabueCentral.Persistence.DatabaseTest.testPersistence(DatabaseTest.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:74)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:673)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:846)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1170)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.runWorkers(TestRunner.java:1147)
at org.testng.TestRunner.privateRun(TestRunner.java:749)
at org.testng.TestRunner.run(TestRunner.java:600)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:317)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:312)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:274)
at org.testng.SuiteRunner.run(SuiteRunner.java:223)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1039)
at org.testng.TestNG.runSuitesLocally(TestNG.java:964)
at org.testng.TestNG.run(TestNG.java:900)
at org.testng.remote.RemoteTestNG.run(RemoteTestNG.java:110)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:205)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:174)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
Error Code: 0
Call: DELETE FROM TAG WHERE (ID = ?)
bind => [1 parameter bound]
Query: DeleteObjectQuery(Tag(id=1, values=[], name=Testtag))
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1611)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:898)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:962)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:631)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:298)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.deleteObject(DatasourceCallQueryMechanism.java:210)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.deleteObject(StatementQueryMechanism.java:104)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeDatabaseQuery(DeleteObjectQuery.java:218)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:798)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:108)
at org.eclipse.persistence.queries.DeleteObjectQuery.executeInUnitOfWorkObjectLevelModifyQuery(DeleteObjectQuery.java:119)
at org.eclipse.persistence.queries.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:85)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1737)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:336)
at org.eclipse.persistence.internal.sessions.CommitManager.deleteAllObjects(CommitManager.java:285)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1444)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1531)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:277)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1169)
at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:132)
... 33 more
Caused by: org.postgresql.util.PSQLException: FEHLER: Aktualisieren oder Löschen in Tabelle „tag“ verletzt Fremdschlüssel-Constraint „fk_tagvalue_parent_id“ von Tabelle „tagvalue“
Detail: Auf Schlüssel (id)=(1) wird noch aus Tabelle „tagvalue“ verwiesen.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:334)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)
... 59 more
我也试图在删除之前先从数据库中获取要删除的标签,但是返回的实例在values
列表中没有任何项目。所以我最后的猜测是,我必须自己填写列表 values
?
就像我最后的建议一样,我必须自己填写 parent 的列表。所以现在没有更多的错误了。
我改变了这个方法:
public static void addTagValue(final TagValue value) throws Exception {
manager.getTransaction().begin();
manager.persist(value);
manager.getTransaction().commit();
}
至:
public static void addTagValue(final TagValue value) throws Exception {
manager.getTransaction().begin();
value.getParent().getValues().add(value);
manager.persist(value);
manager.getTransaction().commit();
}
这就是我之前没有调查的原因:
首先,我不知何故认为 mappedBy
会自动完成这项工作。
此外,我使用 lombok 生成我的 setter 和 getter,并通过 @Data
注释这样做。此注释生成了所有 setter 和 getter,还生成了 toString()
和 hashCode()
方法。当我将一个项目添加到 values
列表时,hashCode()
方法产生了一个 Whosebug,我必须先解决这个问题。