【问题标题】:Loading and sorting two OneToMany-relationships at once with JPA使用 JPA 一次加载和排序两个 OneToMany 关系
【发布时间】:2014-03-01 19:22:55
【问题描述】:

长话短说,我正在尝试在网站上显示餐厅菜单。一页(或您喜欢的 URL)应该只显示一个菜单。在这一点上,餐厅/菜单并不是很重要,但也许它有助于让事情变得更清晰。

主要实体:

  • Menu(“容器”)
  • Category(菜单有几个类别,如开胃菜、软饮料等)
  • Item(Category 包含菜肴、饮料等,它们是 Items)

如上所述,目标是一次加载单个但完整的菜单及其所有类别和类别的项目,或者至少加载少量查询(给定特定的菜单 ID)。在第一种天真的方法中,我使用了以下 JPQL 查询:

SELECT DISTINCT m FROM Menu m JOIN FETCH m.categories c JOIN FETCH c.items i WHERE m.id = :menuId

查询按预期工作,但还有另一个要求。正如您在上图中看到的,类别和项目有一个名为 orderNo 的属性(例如 1、2、3、4 ...) - 此属性的唯一目的是控制类别和项目内部的顺序类别应该稍后出现在网站上(当然,开胃菜类别应该在主菜类别之前呈现,然后是甜点类别,简而言之。类别内的项目也是如此)。

这是我目前的问题。选项:

  • 让数据库进行排序
  • 收到无序数据后在我的应用程序中进行排序

我假设您会像我一样更喜欢第一个选项,但这并不像我想象的那么容易(嗯,它从来都不是......)。我的实体的简化版本如下所示:

@Entity
public class Menu {
    // ...
    @OneToMany(mappedBy="menu")
    private Set<Category> categories;
}

@Entity
public class Category {
    // ...
    @ManyToOne
    private Menu menu;
    @OneToMany(mappedBy="category")
    private Set<Item> items;
}

@Entity
public class Item {
    // ...
    @ManyToOne
    private Category category;
}

我希望我可以使用 ORDER BY i.orderNo asc, c.orderNo asc 之类的东西从上面扩展 JPQL 查询,但这并没有成功。然后我怀疑Set 的类型有问题,并用List 替换了这两种情况。这导致了MultipleBagFetchException(“无法同时获取多个包”)。 我的意图(获得一个具有排序列表的排序类别列表的实体)对于 JPA 根本不可行吗?我的 JPA 提供程序是 Hibernate,但如果需要,我可以更改它。

编辑:

只是为了让您了解数据量:平均菜单有大约 7 个类别,每个类别有大约 10 个项目。 如果您认为我的整个模型需要改进,那么我愿意接受其他方法。

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    一个想法可能是使用@OneToMany 反向映射和@OrderBy。

    我认为您不需要该查询。以下可以加载给定 ID 的菜单

    from Menu m where m.id = ID
    

    该查询将获取您的菜单对象,并且所有反向映射都将按您的 @OrderBy 注释排序

    【讨论】:

    • 谢谢。使用@OrderBy 绝对有帮助!但是对于您的小查询,我只获得菜单本身,并且类别/项目在单独的查询中加载,无论我是否在我的实体中使用FetchType.EAGER。我认为在使用 JPQL 时会忽略 fetchtype 吗?因此,如果我没记错的话,我有 2 个选项:使用 @OrderBy + 我自己的上面查询或使用 @OrderBy + FetchType.EAGER + JPA 的 find 而不是 JPQL。你怎么看?这两个选项都有效,但也许您有更好的主意。
    • @cara 看看这里。希望对你有用stackoverflow.com/questions/2593029/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 1970-01-01
    • 2010-10-27
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多