【问题标题】:hibernate/jpa ignoring LAZY FETCHING in @XxxToOne relationshiphibernate/jpa 忽略 @XxxToOne 关系中的 LAZY FETCHING
【发布时间】: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),因此杰克逊由于通过引用链的无限递归(StackOverflowError)而中断,如下所示:

org.glassfish.jersey.server.internal.process.MappableException: com.fasterxml.jackson.databind.JsonMappingException:无限 递归(StackOverflowError)(通过引用链: 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: 做我想做的事情的最佳方式是什么?

非常感谢

【问题讨论】:

  • 我怀疑问题可能不是由于ManyToOneLazyEager。您可能需要为杰克逊打破这个循环,我相信您可能需要将@JsonIgnore 放在关联的一侧。
  • @MadhusudanaReddySunnapu 为什么你认为延迟获取对我没有帮助?
  • 一旦您将 ManyToOne 指定为 Lazy,hibernate 就会尊重这一点,并且不会影响 ManyToOne。但是,我认为正在发生的是,随后在杰克逊反序列化期间,它也尝试反序列化 ManyToOne 关联,除非我们告诉杰克逊忽略它,因此它会导致此时获取 ManyToOne 并随后进入反序列化周期。
  • 我没有尝试过,但为了排除休眠,您可能需要手动创建 ProductItem 和 Receptacle 对象,并在 OneToMany 和 ManyToOne 设置器中手动关联它们,并尝试对此对象进行杰克逊反序列化。
  • 我在杰克逊开始之前关闭了 entityManager... 我想知道 hibernate 是否知道父对象已经在缓存中,因此它会自动创建循环,因此延迟获取意味着不要去数据库获取对象,但如果已经在缓存中,则构建它。有意义吗?

标签: java hibernate jpa fetch jpa-2.1


【解决方案1】:

根据 JPA 规范,延迟加载是提供者可以完全忽略的提示,完全取决于提供者(此处为休眠)是否考虑它或忽略它(还考虑到单值关联 -OneToOne 和 ManyToOne - 默认情况下急切加载)....所以你不能依赖它。

关于递归问题,请查看my post here,我遇到了与 gson 类似的问题,这就是我解决它的方法

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 2018-06-07
    • 2017-01-19
    • 2015-06-18
    • 2016-08-31
    • 1970-01-01
    • 2011-06-05
    相关资源
    最近更新 更多