Java EclipseLink 2.3.3无法更新PostgreSQL上的版本化实体

Java EclipseLink 2.3.3无法更新PostgreSQL上的版本化实体,java,postgresql,jpa,eclipselink,Java,Postgresql,Jpa,Eclipselink,我有一个简单的实体(一些不相关的字段被简化): 我想通过使用如下JPA更新查询将true设置为initializationInProgress对所有租户进行批量更新: entityManager.createQuery( "UPDATE Tenant t " + "SET t.initializationInProgress = :ip") .setParameter("ip", initializationInProgre

我有一个简单的实体(一些不相关的字段被简化):

我想通过使用如下JPA更新查询将
true
设置为
initializationInProgress
对所有租户进行批量更新:

    entityManager.createQuery(
            "UPDATE Tenant t " +
            "SET t.initializationInProgress = :ip")
        .setParameter("ip", initializationInProgress)
        .executeUpdate();
这在
EclipseLink 2.2.1
中运行良好。但是,当我在版本
2.3.3
中尝试相同的操作时,我得到一个错误:

Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.3.v20120629-r11760): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: more than one row returned by a subquery used as an expression
Error Code: 0
Call: UPDATE tenant SET version = (SELECT (version + ?) FROM tenant WHERE ID = tenant.ID), init_in_progress = ?
    bind => [1, true]
Query: UpdateAllQuery(referenceClass=Tenant sql="UPDATE tenant SET version = (SELECT (version + ?) FROM tenant WHERE ID = tenant.ID), init_in_progress = ?")
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:333)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.processExceptionForCommError(DatabaseAccessor.java:1494)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:838)
    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.updateAll(DatasourceCallQueryMechanism.java:789)
    at org.eclipse.persistence.queries.UpdateAllQuery.executeDatabaseQuery(UpdateAllQuery.java:153)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:844)
    at org.eclipse.persistence.queries.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:743)
    at org.eclipse.persistence.queries.ModifyAllQuery.executeInUnitOfWork(ModifyAllQuery.java:145)
    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.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1463)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeUpdate(EJBQueryImpl.java:540)
    at com.example.dao.impl.tenant.TenantRepositoryImpl.updateAllTenantsInitializationStatus(TenantRepositoryImpl.java:100)
有人熟悉这个bug吗?任何已知的解决方法/修复(除了不更改
EclipseLink
version)?谢谢你的帮助


顺便说一句,我使用的是
PostgreSQL 9.1

这最初看起来像是一个数据问题,在
租户中有多个具有相同ID的行。。。但这实际上是EclipseLink查询的一个问题。因为这是一个生成的查询,所以您的手上似乎有一个(严重的)Eclipse错误

更新:见

查询实际上应该将内部引用别名为
租户
,例如:

UPDATE tenant SET version = (SELECT (t2.version + ?) FROM tenant t2 WHERE t2.ID = tenant.ID), init_in_progress = ?
未能添加此别名表示
ID=tenant.ID
表示
tenant.ID=tenant.ID
。。。这总是正确的,因此子查询匹配
租户的每一行

请观看此演示:

CREATE TABLE tenant ( ID integer primary key, version integer );
INSERT INTO tenant ( id, version ) values (1,0), (2,0), (3,0);

BEGIN;

PREPARE testq(integer) AS 
UPDATE tenant SET version = (SELECT (version + $1) FROM tenant WHERE ID = tenant.ID);

regress=> EXECUTE testq(1);
ERROR:  more than one row returned by a subquery used as an expression

ROLLBACK;
更正的查询:

BEGIN;

PREPARE testq2(integer) AS 
UPDATE tenant SET version = (SELECT (version + $1) FROM tenant t2 WHERE t2.ID = tenant.ID);

regress=> EXECUTE testq2(1);
UPDATE 3

ROLLBACK;

这似乎是一个日食虫。除了作为本机SQL进行批量更新之外,我看不出您在代码中可以做多少其他事情。

这最初看起来像是一个数据问题,在
租户中有多个具有相同ID的行。。。但这实际上是EclipseLink查询的一个问题。因为这是一个生成的查询,所以您的手上似乎有一个(严重的)Eclipse错误

更新:见

查询实际上应该将内部引用别名为
租户
,例如:

UPDATE tenant SET version = (SELECT (t2.version + ?) FROM tenant t2 WHERE t2.ID = tenant.ID), init_in_progress = ?
未能添加此别名表示
ID=tenant.ID
表示
tenant.ID=tenant.ID
。。。这总是正确的,因此子查询匹配
租户的每一行

请观看此演示:

CREATE TABLE tenant ( ID integer primary key, version integer );
INSERT INTO tenant ( id, version ) values (1,0), (2,0), (3,0);

BEGIN;

PREPARE testq(integer) AS 
UPDATE tenant SET version = (SELECT (version + $1) FROM tenant WHERE ID = tenant.ID);

regress=> EXECUTE testq(1);
ERROR:  more than one row returned by a subquery used as an expression

ROLLBACK;
更正的查询:

BEGIN;

PREPARE testq2(integer) AS 
UPDATE tenant SET version = (SELECT (version + $1) FROM tenant t2 WHERE t2.ID = tenant.ID);

regress=> EXECUTE testq2(1);
UPDATE 3

ROLLBACK;

这似乎是一个日食虫。除了作为本机SQL进行批量更新之外,我看不出在代码中还有什么可以做的。

这看起来像是一个错误,但对我来说也是,但我找不到错误报告,所以我想可能我做错了什么,因为这个错误似乎真的很严重。谢谢你在这个话题上的努力。它看起来像是一个错误,但对我来说也是,但是我找不到错误报告,所以我想可能我做错了什么,因为这个错误似乎真的是一个主要的错误。谢谢你在这个话题上的努力。