JPA 查询,oneToMany 或 ManyToOne,都应该工作吗?

发布于 2024-10-15 06:32:03 字数 1976 浏览 4 评论 0原文

我正在将一些代码从旧的 OpenJPA 实现移植到更新的实现,特别是

OpenJPA 2.1.0-SNAPSHOT版本 ID: openjpa-2.1.0-SNAPSHOT-r422266:990238

我之前工作的查询在这个新环境中失败了(稍后会详细介绍确切的失败情况),但重铸查询工作得很好。区别在于我从一对多查询的哪一侧开始。我的问题分为两部分:

  1. 是否有“正确”的一面可以开始这样的查询?我们期望这两个查询都能工作吗?
  2. 如果我们期望两者都能工作,我们可以解释我所看到的失败吗?

为了简洁起见,这里的课程被减少了。关系的一侧:

@Entity
@Table(name="CWS_MDS")
public class CwsMd implements Serializable {

    @Id
    Column(name="RSM_ID", unique=true, nullable=false, length=128)
    private String rsmId;

    // ... many elisions ... 

   //bi-directional many-to-one association to CwsPubOperationRef
   @OneToMany(mappedBy="cwsMd")
   private Set<CwsPubOperationRef> cwsPubOperationRefs;

}

另一侧

   @Entity
   @Table(name="CWS_PUB_OPERATION_REF")
   public class CwsPubOperationRef implements Serializable {

  @EmbeddedId
  private CwsPubOperationRefPK id;

 //bi-directional many-to-one association to CwsMd
    @ManyToOne
  @JoinColumn(name="RSM_ID", nullable=false, insertable=false, updatable=false)
  private CwsMd cwsMd;

    // ... more elisions ...
    }

有效的查询:

 <named-query name="good"> <query>   
      SELECT opref FROM CwsPubOperationRef opref
            JOIN opref.cwsMd rsm
            WHERE rsm.rsmId = :rsmId                                                      
  </query>
 </named-query>

无效的查询

  <named-query name="bad"> <query>   
         SELECT opref FROM CwsMd rsm
            JOIN rsm.cwsPubOperationRefs opref
            WHERE rsm.rsmId = :rsmId
     </query> </named-query>

我得到的错误是

 org.apache.openjpa.persistence.PersistenceException: [jcc][t4][10120][10898][3.57.82]   
 Invalid operation: result set is closed. ERRORCODE=-4470, SQLSTATE=null

我在 Windows 上的 WebSphere 8.0 上运行,使用 DB2 作为数据库。

I am porting some code from an old OpenJPA implementation to a more recent one, specifically to

OpenJPA 2.1.0-SNAPSHOTversion id:
openjpa-2.1.0-SNAPSHOT-r422266:990238

My previously working query failed in this new environment (details of the exact failure later) but recasting the query worked just fine. The difference lies in which side of a one-to-many query I start at. My question is in two parts:

  1. Is there a "correct" side from which to start such a query? Would we expect both queries to work?
  2. If we would expect both to work, can we explain the failure I'm seeing.

For the sake of brevity the classes here are rather cut down. One side of the relation:

@Entity
@Table(name="CWS_MDS")
public class CwsMd implements Serializable {

    @Id
    Column(name="RSM_ID", unique=true, nullable=false, length=128)
    private String rsmId;

    // ... many elisions ... 

   //bi-directional many-to-one association to CwsPubOperationRef
   @OneToMany(mappedBy="cwsMd")
   private Set<CwsPubOperationRef> cwsPubOperationRefs;

}

the other side

   @Entity
   @Table(name="CWS_PUB_OPERATION_REF")
   public class CwsPubOperationRef implements Serializable {

  @EmbeddedId
  private CwsPubOperationRefPK id;

 //bi-directional many-to-one association to CwsMd
    @ManyToOne
  @JoinColumn(name="RSM_ID", nullable=false, insertable=false, updatable=false)
  private CwsMd cwsMd;

    // ... more elisions ...
    }

The query that works:

 <named-query name="good"> <query>   
      SELECT opref FROM CwsPubOperationRef opref
            JOIN opref.cwsMd rsm
            WHERE rsm.rsmId = :rsmId                                                      
  </query>
 </named-query>

The one that does not

  <named-query name="bad"> <query>   
         SELECT opref FROM CwsMd rsm
            JOIN rsm.cwsPubOperationRefs opref
            WHERE rsm.rsmId = :rsmId
     </query> </named-query>

The error that I get is

 org.apache.openjpa.persistence.PersistenceException: [jcc][t4][10120][10898][3.57.82]   
 Invalid operation: result set is closed. ERRORCODE=-4470, SQLSTATE=null

I'm running on WebSphere 8.0, on Windows, using DB2 as the database.

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

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

发布评论

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

评论(2

毁虫ゝ 2024-10-22 06:32:03

第二个查询不正确,因为标识变量 opref 引用集合(rsm.cwsPubOperationRefs 是集合)而不是单个值。

在 JPA 2.0 规范中,这是用以下文字来说明的:

使用除 in 以外的集合值路径表达式是非法的
查询的 FROM 子句,除了在
空集合比较表达式,在
collection_member_expression,或作为 SIZE 运算符的参数。

第一个查询完全没问题 - CwsPubOperationRef 因为标识变量引用单个值。

Second query is incorrect, because identification variable opref refers to collection (rsm.cwsPubOperationRefs is collection ) and not to single value.

In JPA 2.0 specification this is told with following words:

It is illegal to use a collection_valued_path_expression other than in
the FROM clause of a query except in an
empty_collection_comparison_expression, in a
collection_member_expression, or as an argument to the SIZE operator.

First query is perfectly fine - CwsPubOperationRef because identification variable refers to single value.

违心° 2024-10-22 06:32:03

您可能会在此特定版本中遇到一些错误。当我尝试设置 OpenJPA fetchSize 时,我还收到结果集已关闭错误。
<>
就我而言,事实证明 OpenJPA query.getResultList() 返回一个代理对象,而不是实际的列表。因此,如果我在将结果列表返回给客户端之前耗尽它,我就不再遇到问题了。
然而,我们还有另一个问题。仅通过设置 fetchBatchSize 就会导致 OpenJPA 生成无效的查询!。当然这是一个错误。

You might be hitting some bug in this particular version. I am also getting Result set is closed error when I try to set OpenJPA fetchSize.
<>
In my case it turns out that OpenJPA query.getResultList() returns a proxy object, not the actual List. So, if I exhaust the result list before returning it to the client, I no longer hit the problem.
However, we have another problem. Just by setting the fetchBatchSize causes OpenJPA to produce a Query which is invalid!. Certainly it's a bug.

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