hibernate/jpa 忽略 @XxxToOne 关系中的 LAZY FETCHING
Posted
技术标签:
【中文标题】hibernate/jpa 忽略 @XxxToOne 关系中的 LAZY FETCHING【英文标题】:hibernate/jpa ignoring LAZY FETCHING in @XxxToOne relationship 【发布时间】:2018-03-21 03:58:08 【问题描述】:我使用 hibernate 5 作为 JPA 实现,我遇到了 @OneToMany 双向关系的问题。
这些是我的实体:
@Entity(name = "product_item")
public class ProductItem
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "receptacle")
private Receptacle receptacle;
...
@Entity(name = "receptacle")
public class Receptacle
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "receptacle", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<ProductItem> productItems = new HashSet<>();
...
我希望这种关系在两个方向上都是惰性的,因为我想通过 FETCH JOIN 手动获取数据,如下面的查询:
String query = "SELECT "
+ " DISTINCT r"
+ " FROM"
+ " receptacle r"
+ " JOIN FETCH product_item pi ON r.id = pi.receptacle.id"
+ " JOIN ereturn er ON er.id = pi.ereturn.id"
+ " WHERE"
+ " r.masterCrossDock IS NULL";
但我的问题是休眠忽略了@ManyToOne(fetch = FetchType.LAZY),因此杰克逊由于通过引用链的无限递归(***Error)而中断,如下所示:
org.glassfish.jersey.server.internal.process.MappableException: com.fasterxml.jackson.databind.JsonMappingException:无限 递归(***Error)(通过引用链: returnitRest.Receptacle["productItems"]->org.hibernate.collection.internal.PersistentSet[0]->returnitRest.ProductItem["receptacle"]->returnitRest.Receptacle["productItems"]->org.hibernate.collection。 internal.PersistentSet[0]->returnitRest.ProductItem["receptacle"]- ...
问题 1: 如何告诉 hibernate 不要获取 @ManyToOne 关系方向?
问题 2: 如果我试图做的事情是不可能的,为什么?
问题 3: 做我想做的事情的最佳方式是什么?
非常感谢
【问题讨论】:
我怀疑问题可能不是由于ManyToOne
是Lazy
或Eager
。您可能需要为杰克逊打破这个循环,我相信您可能需要将@JsonIgnore
放在关联的一侧。
@MadhusudanaReddySunnapu 为什么你认为延迟获取对我没有帮助?
一旦您将 ManyToOne 指定为 Lazy,hibernate 就会尊重这一点,并且不会影响 ManyToOne。但是,我认为正在发生的是,随后在杰克逊反序列化期间,它也尝试反序列化 ManyToOne 关联,除非我们告诉杰克逊忽略它,因此它会导致此时获取 ManyToOne 并随后进入反序列化周期。
我没有尝试过,但为了排除休眠,您可能需要手动创建 ProductItem 和 Receptacle 对象,并在 OneToMany 和 ManyToOne 设置器中手动关联它们,并尝试对此对象进行杰克逊反序列化。
我在杰克逊开始之前关闭了 entityManager... 我想知道 hibernate 是否知道父对象已经在缓存中,因此它会自动创建循环,因此延迟获取意味着不要去数据库获取对象,但如果已经在缓存中,则构建它。有意义吗?
【参考方案1】:
根据 JPA 规范,延迟加载是提供者可以完全忽略的提示,完全取决于提供者(此处为休眠)是否考虑它或忽略它(还考虑到单值关联 -OneToOne 和 ManyToOne - 默认情况下急切加载)....所以你不能依赖它。
关于递归问题,请查看my post here,我遇到了与 gson 类似的问题,这就是我解决它的方法
【讨论】:
以上是关于hibernate/jpa 忽略 @XxxToOne 关系中的 LAZY FETCHING的主要内容,如果未能解决你的问题,请参考以下文章