【问题标题】:OneToMany LazyInitializationException when collection is empty集合为空时的 OneToMany LazyInitializationException
【发布时间】:2019-03-11 22:13:43
【问题描述】:

我知道同一个主题有几十个问题,但我不明白为什么它们在我的情况下不起作用。

我有两张表,一张名为 Account,一张名为 CustomerRelations,它们之间存在一对多的关系(一个帐户可以属于多个 customerRelations...一个帐户可以在没有其他客户关系的情况下存在但客户关系只能附加到现有帐户)

这是它们在我的实体类中的注释方式:

账户表:

@OneToMany(mappedBy = "account", cascade = CascadeType.ALL, orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<CustomRel> customRels = new ArrayList<>();

客户关系表:

@ManyToOne(fetch = FetchType.EAGER)
private Account account;

我有业务逻辑,我想根据帐户表中保存的特定日期调用查询:

@NamedQuery(name = Account.FIND_BY_ACC_NBR, query = "select acc from Account acc where acc.accountNumber =:accountNumber")

此查询提供了帐户表中的正确数据,但对于字段 customerRels,我得到以下异常:

**Unable to evaluate the expression Method threw 'org.hibernate.LazyInitializationException' exception.**

在我的 Account 对象上调用 getter 方法时也是如此:

在我的示例中,有一个 account 对象,其中包含一个空的 customerRels 列表。所以与accountId关联的数据库中没有customerRels记录。

据我所知,我的 Account 实体类中的 fetchType 是惰性的 - 默认情况下,对吧?

在我创建表的 SQL 脚本中,在 CustomerRelations 表中只添加了一个 account_id,在 Account 表中没有对子对象的引用。

我知道这是一个非常平庸的问题,但我需要一些帮助。我应该修改我的 JPQL 查询吗?

【问题讨论】:

    标签: hibernate jpa jpql eager


    【解决方案1】:

    OneToMany 是默认 LAZY 并且您正在访问休眠会话之外的集合(运行事务)。即使列表是空的,也需要选择来初始化惰性集合。持久性无法知道集合中是否有项目,除非它在 ​​DB 中检查。

    选项:

    1. FetchType.EAGER
    2. join fetch rels r 在您的 JPQL 中
    3. 在事务/会话中初始化集合

    【讨论】:

    • FetchType.EAGER 解决了我的问题。另外,我必须将 @JoinColumn 添加到我的 ManyToOne 实体字段中。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 2021-08-21
    • 1970-01-01
    • 2016-07-11
    • 2014-02-03
    相关资源
    最近更新 更多