JPA Hibernate 意外获取了@OneToOne 映射实体的记录,我应该将映射更改为@ManyToOne 还是执行其他操作?
JPA Hibernate unexpectedly fetches records of @OneToOne mapped entity, should I change mapping to @ManyToOne or do something else?
我有一个具有 @OneToOne
映射子实体的实体:
@Entity @Table
public class BaseEntity {
@Id
private String key;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private InnerEntity inner;
}
@Entity @Table
public class InnerEntity {
private String data;
}
在我决定获取命名查询中的所有记录 (SELECT e FROM BaseEntity e
) 之前,它在持久化和合并操作上工作得很好。问题是在调用它之后,Hibernate 从 BaseEntity 获取所有记录,然后对每个 InnerEntity 执行不同的查询。因为 table 很大,所以需要很多时间和内存。
首先,我开始调查是否在 运行 代码中的任何地方调用了 getInner()
。然后我尝试将 fetchType
更改为 EAGER
以检查 Hibernate 是否会通过一个查询获取所有内容。它没有。另一个尝试是将映射更改为 @ManyToOne
。为此,我将 updatable/insertable=false
添加到 @JoinColumn
注释。获取开始完美地工作 - 一个 SELECT
没有任何 JOIN
(我将 EAGER
改回 LAZY
),但是更新开始出现问题。 Hibernate 期望 InnerEntity
首先被持久化,但是没有 属性 主键。当然我可以这样做并且明确坚持 InnerEntity
先调用 setKey()
,但我宁愿不用这个来解决这个问题。
有什么想法吗?
当使用 HQL 时,hibernate 不考虑注释,所以你应该告诉它如何工作。
在您的情况下,您应该像这样正确处理 HQL:
SELECT e FROM BaseEntity as e left join fetch e.inner
如果您希望 inner
字段按需加载并且您的关系是 @OnToOne
您可以试试这个
@OneToOne(fetch = FetchType.LAZY, optional = false)
我有一个具有 @OneToOne
映射子实体的实体:
@Entity @Table
public class BaseEntity {
@Id
private String key;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private InnerEntity inner;
}
@Entity @Table
public class InnerEntity {
private String data;
}
在我决定获取命名查询中的所有记录 (SELECT e FROM BaseEntity e
) 之前,它在持久化和合并操作上工作得很好。问题是在调用它之后,Hibernate 从 BaseEntity 获取所有记录,然后对每个 InnerEntity 执行不同的查询。因为 table 很大,所以需要很多时间和内存。
首先,我开始调查是否在 运行 代码中的任何地方调用了 getInner()
。然后我尝试将 fetchType
更改为 EAGER
以检查 Hibernate 是否会通过一个查询获取所有内容。它没有。另一个尝试是将映射更改为 @ManyToOne
。为此,我将 updatable/insertable=false
添加到 @JoinColumn
注释。获取开始完美地工作 - 一个 SELECT
没有任何 JOIN
(我将 EAGER
改回 LAZY
),但是更新开始出现问题。 Hibernate 期望 InnerEntity
首先被持久化,但是没有 属性 主键。当然我可以这样做并且明确坚持 InnerEntity
先调用 setKey()
,但我宁愿不用这个来解决这个问题。
有什么想法吗?
当使用 HQL 时,hibernate 不考虑注释,所以你应该告诉它如何工作。 在您的情况下,您应该像这样正确处理 HQL: SELECT e FROM BaseEntity as e left join fetch e.inner
如果您希望 inner
字段按需加载并且您的关系是 @OnToOne
您可以试试这个
@OneToOne(fetch = FetchType.LAZY, optional = false)