当前位置: 首页 > 知识库问答 >
问题:

hibernate/jpa忽略@XxxToOne关系中的延迟抓取

阎弘雅
2023-03-14

我使用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"; 

但我的问题是hibernate忽略了@ManyToOne(fetch=FetchType.LAZY),因此Jackson由于引用链的无限递归(StackOverflowerr)而中断,如下所示:

org.glassfish.jersey.server.internal.process。MappableException:com.fasterxml.jackson.databind。JsonMappingException:无限递归(StackOverflowerr)(通过引用链:ReturnitTest.Receptor[“productItems”]-

问题1:我怎么能告诉冬眠不去获取@ManyToOne关系方向?

问题2:如果我想做的是不可能的,为什么?

问题3:做我想做的事情的最佳方式是什么?

非常感谢你们

共有1个答案

张丰
2023-03-14

根据JPA规范,延迟加载是提供者可以完全忽略的提示,完全由提供者(这里是hibernate)来考虑或忽略它(同时考虑到单值关联-OneToOne和ManyToOne-在默认情况下是急切加载的)…所以你不能依赖它。

关于递归问题,请查看我的帖子,我在gson上也有类似的问题,这就是我解决它的方法

 类似资料:
  • 我与Jpa一起使用springboot(spring-boot-starter-父2.3.0版本)。我有作为父实体的User类和作为子实体的UserEmails。 用户实体 用户角色实体 问题是,即使我在关系的两边都使用fetch类型作为懒惰,但当我调用getUserById或getAllUsers时,jpa也会加载用户电子邮件。 用户服务简介 UserDAO

  • 问题内容: 在大型应用程序中,我与EAGER的关系存在问题。此应用程序中的某些实体与其他实体具有关联。这在某些功能上成为“毒药”。 现在,我的团队需要优化此功能,但是 我们无法将访存类型更改为LAZY ,因为我们需要重构整个应用程序。 所以,我的问题是:是否有一种方法可以执行特定的查询而忽略我返回的实体中的EAGER关联? 示例:当我有这个实体Person时,我在查询以查找Person时不带地址列

  • 问题内容: 我以这样一种方式进行了JPA设置:如果我不使用延迟加载,则几乎将加载整个数据库。我也直接在模型上使用序列化,因此有时我需要初始化代理。 我只想在集合上使用延迟加载。急切地获取一些奇异实体的事实就很好了。但是,无论我如何尝试设置集合,我都永远不会得到代理集合,而我总是会得到完全加载的集合。 这是一些示例代码: 所以这里的问题是,当我检查调试器时,答复的persistantBag-list

  • 我需要从Rest控件获取一个实体及其集合,但我对spring data JPA有一个非常奇怪的行为。 我对带有懒惰加载的实体有一种莫名其妙的关系。

  • 好的,对于前面提到的技术,这是一个非常奇怪的行为,我有一个控制器,它调用一个服务,这调用一个dao。传递给持久化的实体有一个带有注释的字段,当我为dao或服务运行测试并插入重复值时,会抛出异常这是正常的,是预期的行为。但是,当我运行web应用程序时,异常会在服务完成执行后抛出。在执行dao时不会。因此,这迫使我在控制器中捕获异常,而不是在服务中。 控制器启动 服务//继续 DAO//继续(但是此时

  • 应用程序模块: app-routing.module.ts: 实体/实体-routing.module.ts: 实体/实体.组件. ts: 我还尝试使用以下方法在实体模块中定义路由,但组件仍会显示为导航到 /list,而不是 /entities/list。 我做错了什么?任何帮助是值得赞赏的!