JPA EclipseLink @ElementCollection 未正确更新

发布于 2025-01-08 15:03:55 字数 6762 浏览 1 评论 0原文

针对 OracleXE 使用 EclipseLink 2.3.2 和静态编织(Maven 插件)。

我有以下实体

@Entity
@Table(name="LIST")
public class List {

    ...Id...

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "LIST_CONTENTS", joinColumns = @JoinColumn(name = "LIST_ID"))
    @OrderColumn(name = "SEQ")
    @Column(name = "CONTENT", length = 4000)
    private java.util.List<String> contents;

}

,当我通过执行以下操作更新内容时:

// newContents is a String[]
em.getTransaction().begin();
List list = em.find(List.class,id);
list.setContents(new ArrayList<String>(Arrays.asList(newContents)));
em.getTransaction().commit();

我收到重复的密钥错误 - 就像它没有删除旧数据一样

> Error Code: 1 Call: INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)
>         bind => [3 parameters bound] Query: DataModifyQuery(sql="INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)")
>         at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
>         at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
>         at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512)
>         ... 54 more Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461):
> org.eclipse.persistence.exceptions.DatabaseException Internal
> Exception: java.sql.SQLIntegrityConstraintViolationException:
> ORA-00001: unique constraint (ANNEX.NIBR_LIST_CONTENTS_PK) violated
> 
> Error Code: 1 Call: INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)
>         bind => [3 parameters bound] Query: DataModifyQuery(sql="INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)")
>         at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
>         at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:253)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelectCall(DatasourceCallQueryMechanism.java:236)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelect(DatasourceCallQueryMechanism.java:216)
>         at org.eclipse.persistence.internal.queries.StatementQueryMechanism.executeNoSelect(StatementQueryMechanism.java:115)
>         at org.eclipse.persistence.queries.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:85)
>         at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
>         at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:743)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
>         at org.eclipse.persistence.mappings.DirectCollectionMapping.performDataModificationEvent(DirectCollectionMapping.java:2080)
>         at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:157)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3799)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1415)
>         at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:636)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1505)
>         at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:267)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1143)
>         at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
>         ... 56 more Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique
> constraint (ANNEX.NIBR_LIST_CONTENTS_PK) violated
> 
>         at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
>         at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
>         at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:837)
>         at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:445)
>         at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
>         at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
>         at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
>         at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1010)
>         at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1315)
>         at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
>         at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3657)
>         at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:831)
>         ... 81 more

,我不知道设置中出了什么问题 - 我正在使用 Flyway 来执行我手写的 SQL/DDL。任何帮助表示赞赏。

Using EclipseLink 2.3.2 with static weaving (Maven plugin) against OracleXE.

I have the following Entity

@Entity
@Table(name="LIST")
public class List {

    ...Id...

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "LIST_CONTENTS", joinColumns = @JoinColumn(name = "LIST_ID"))
    @OrderColumn(name = "SEQ")
    @Column(name = "CONTENT", length = 4000)
    private java.util.List<String> contents;

}

and when I update the contents by doing the following:

// newContents is a String[]
em.getTransaction().begin();
List list = em.find(List.class,id);
list.setContents(new ArrayList<String>(Arrays.asList(newContents)));
em.getTransaction().commit();

I get a duplicate key error - like it didn't delete the old data

> Error Code: 1 Call: INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)
>         bind => [3 parameters bound] Query: DataModifyQuery(sql="INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)")
>         at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:102)
>         at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commit(EntityTransactionImpl.java:63)
>         at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:512)
>         ... 54 more Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461):
> org.eclipse.persistence.exceptions.DatabaseException Internal
> Exception: java.sql.SQLIntegrityConstraintViolationException:
> ORA-00001: unique constraint (ANNEX.NIBR_LIST_CONTENTS_PK) violated
> 
> Error Code: 1 Call: INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)
>         bind => [3 parameters bound] Query: DataModifyQuery(sql="INSERT INTO NIBR_LIST_CONTENTS (LIST_ID, CONTENT,
> SEQ) VALUES (?, ?, ?)")
>         at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeNoSelect(DatabaseAccessor.java:906)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:592)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:535)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1717)
>         at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:253)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:207)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:193)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelectCall(DatasourceCallQueryMechanism.java:236)
>         at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeNoSelect(DatasourceCallQueryMechanism.java:216)
>         at org.eclipse.persistence.internal.queries.StatementQueryMechanism.executeNoSelect(StatementQueryMechanism.java:115)
>         at org.eclipse.persistence.queries.DataModifyQuery.executeDatabaseQuery(DataModifyQuery.java:85)
>         at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
>         at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:743)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2871)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1516)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1498)
>         at org.eclipse.persistence.mappings.DirectCollectionMapping.performDataModificationEvent(DirectCollectionMapping.java:2080)
>         at org.eclipse.persistence.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:157)
>         at org.eclipse.persistence.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:3799)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase(UnitOfWorkImpl.java:1415)
>         at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase(RepeatableWriteUnitOfWork.java:636)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1505)
>         at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitRootUnitOfWork(RepeatableWriteUnitOfWork.java:267)
>         at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitAndResume(UnitOfWorkImpl.java:1143)
>         at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.commitInternal(EntityTransactionImpl.java:84)
>         ... 56 more Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique
> constraint (ANNEX.NIBR_LIST_CONTENTS_PK) violated
> 
>         at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:440)
>         at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
>         at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:837)
>         at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:445)
>         at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:191)
>         at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:523)
>         at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
>         at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1010)
>         at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1315)
>         at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3576)
>         at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3657)
>         at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
>         at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:831)
>         ... 81 more

I've no idea what's wrong in the setup - I am using flyway to execute the SQL/DDL that I've written by hand. Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

荒人说梦 2025-01-15 15:03:55

根据 EclipseLink 处理 ElementCollection(顺序)元素的方式,您不能拥有连接列和顺序列的主键。 EclipseLink 确实可以使用可能包含也可能不包含序列列的 SQL 正确处理更新,但顺序是这样的:相同的 LIST_ID、SEQ 组合可以在事务中同时存在。

删除主键,一切正常。

Based on how EclipseLink processes the elements of the ElementCollection (order), you cannot have a primary key of the join columns and the order column. EclipseLink does handle updates properly with SQL that may or may not include the sequence column, but the order is such that the same LIST_ID, SEQ combination can exist for the same time in the transaction.

Remove the primary key and it all works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文