JPA 查询,oneToMany 或 ManyToOne,都应该工作吗?
我正在将一些代码从旧的 OpenJPA 实现移植到更新的实现,特别是
OpenJPA 2.1.0-SNAPSHOT版本 ID: openjpa-2.1.0-SNAPSHOT-r422266:990238
我之前工作的查询在这个新环境中失败了(稍后会详细介绍确切的失败情况),但重铸查询工作得很好。区别在于我从一对多查询的哪一侧开始。我的问题分为两部分:
- 是否有“正确”的一面可以开始这样的查询?我们期望这两个查询都能工作吗?
- 如果我们期望两者都能工作,我们可以解释我所看到的失败吗?
为了简洁起见,这里的课程被减少了。关系的一侧:
@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:
- Is there a "correct" side from which to start such a query? Would we expect both queries to work?
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第二个查询不正确,因为标识变量 opref 引用集合(rsm.cwsPubOperationRefs 是集合)而不是单个值。
在 JPA 2.0 规范中,这是用以下文字来说明的:
第一个查询完全没问题 - 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:
First query is perfectly fine - CwsPubOperationRef because identification variable refers to single value.
您可能会在此特定版本中遇到一些错误。当我尝试设置 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.