java - J2EE 实体中的深度预加载

标签 java jakarta-ee jpa jta

我在使用 EJB 应用程序的 J2EE 中有一个 3 层模型:Cart,它有许多 LineItem,每个 LineItem 都有许多 Book(Book 不一定指 Line Item,它不是 2 向的)。

Cart(1) <--> (M) LineItem (1) --> (M) Book 

我希望将其全部加载,即当我提取购物车时,它还应该加载其所有行项目和所有这些书籍,并使用最少数量的 SQL 查询(我正在使用关系数据库,例如 MySQL)。它可以通过 3 个查询来完成,每个查询对应一种类型的对象。设置“FetchType.EAGER”会导致加载所有对象,但它有“2+n”次调用:1 个购物车查询(显然),另一个查询行项目,但随后必须对书籍进行 n 次查询,其中 n 是订单项的数量。

我曾经使用 Ruby on Rails,其中使用急切加载(使用包含)可以满足我的需要。我也可以用 J2EE 来做吗?

(注意:联接可能是一个选项,但我希望从查询中自动填充实体,尽管我认为联接不太舒服)。

我的代码示例:

@Entity
public class Cart implements Serializable {
    @OneToMany(cascade=ALL, mappedBy="cart", fetch = FetchType.EAGER)
    private List<LineItem> lineItems;
}

@Entity
public class LineItem implements Serializable {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="cart_id", referencedColumnName = "id")
    private Cart cart;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="book_id", referencedColumnName = "id")
    private Book book;
}

@Entity
public class Book implements Serializable {
   ...
}

以下是 SQL 查询示例,其中购物车有 3 个行项目:

SELECT id, name FROM carts WHERE (id = 19)
SELECT id, quantity, book_id, cart_id FROM line_items WHERE (cart_id = 19)
SELECT id, description, name, price FROM books WHERE (id = 4)
SELECT id, description, name, price FROM books WHERE (id = 3)
SELECT id, description, name, price FROM books WHERE (id = 1)

最佳答案

标准 JPA 提供 join fetch ,它标记一个要急切获取的关系,就像通过注释标记为急切一样。在您的情况下,只需要 join fetch lineItems,因为 book 将与每个 LineItem 一起加载在单个查询中。

使用 JPA 2.1,您可以使用 Entity graph - 您不需要修改您的查询,只需将一个描述符附加到您的查询中,该描述符定义应立即获取哪些关系。

如果您想优化到尽可能少的查询,您可能需要使用 batch fetching ,这在某些 JPa 提供商中可用。但请注意,没有标准化的方法来打开此功能 - 我只是链接到如何使用 EclipseLink 进行此操作。

关于java - J2EE 实体中的深度预加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33543899/

相关文章:

java - CQ 5.5 i18n 和接受语言 header

java - 单例 EJB 中的系统异常

java - 字符串到对象的转换,

java - 用另一个 List 扩展 ImmutableList.of()

css - 溢出长文本

java - Apache httpd CPU 使用率高

JPA Eclipselink : How to find which relationship is causing error

java - 使用 hbm.xml 的 Hibernate 中主键的强制 setter

java - 将 Ordinal Enum 值设置为从 1 而不是 0 开始

java - 如何将整数的小映射表示为数组?