【问题标题】:Duplicates in OneToMany annotated ListOneToMany 注释列表中的重复项
【发布时间】:2014-01-12 01:00:18
【问题描述】:

我正在使用 JPA 2 + Hibernate 4.2.6 开发一个 Java 项目,但我遇到了一个奇怪的行为。

在我的模型中,我有两个相关的实体:QuestionAnswer

@Entity
public class Question {
    // ...

    @OneToMany(mappedBy = "question", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<Answer> answers;

    // ...
}


@Entity
public class Answer {
    // ...

    @ManyToOne(optional = false)
    @JoinColumn(name = "question_id", nullable = false)
    private Question question;

    // ...
}

这很完美:与某个Question 相关的所有Answers 都已正确加载。

但现在我需要将answers 的提示从Set 更改为List。我更改了类型并再次运行应用程序,现在我在answers 中得到了几个重复... 为什么有可能?我知道List 允许重复,但我的数据库中没有重复记录,为什么我会得到这些?

我在以前版本的 Hibernate 中读到了一些类似的错误,但我希望它们在上一个版本中得到解决......我错了吗?

注意我需要将Set 更改为List,因为我需要保留有关订单 的信息以获取答案,并可能更改此订单。

【问题讨论】:

    标签: java hibernate jpa collections one-to-many


    【解决方案1】:

    您很可能会得到重复,因为当使用 fetch=FetchType.EAGER, Hibernate uses an outer join 来获取连接表中的数据时。

    尝试移除急切获取以确认。如果是这种情况,您应该删除 Eager fetching,保留 Set 而不是 List,或者编写 JPQL 查询来准确检索您需要的内容。

    来自Hibernate doc

    推荐的方法是对所有静态提取使用 LAZY 定义并通过 JP-QL 动态覆盖此选择。

    【讨论】:

    • 您还可以将@Fetch(FetchMode.SELECT) 与 fetch=FetchType.EAGER 一起使用。有了这个,就不用从List改成Set了。
    • 我得到了 38000 行,而应该只有 38 行。那只是杀死了我的 ECS 实例。使用Set 真的救了我。没有尝试@nimo23 的方法。有什么比将List 替换为Set 更好的呢?这两种方法在效率方面如何比较?
    • @ParamvirSinghKarwal - 如果你使用 Set 你不能有订单(所以第一个答案,第二个答案等)。据我了解,FetchMode.SELECT 效率较低。
    猜你喜欢
    • 2012-10-26
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    相关资源
    最近更新 更多