Java J2EE实体中的深度负载

Java J2EE实体中的深度负载,java,jakarta-ee,jpa,jta,Java,Jakarta Ee,Jpa,Jta,我在J2EE中使用EJB应用程序:Cart有一个三层模型,它有许多行项目,每个行项目都有许多书(书不一定指行项目,它不是双向的) 标准JPA提供了一个标签,它标记了一个急切地获取的关系,就好像它是通过注释标记为急切的一样。在您的情况下,只需加入fetch行项目,因为书籍将在单个查询中急切地加载每个行项目 在JPA2.1中,您可以使用-您不需要修改查询,只需在查询中附加一个描述符,定义应该急切获取哪些关系 如果您希望优化到尽可能少的查询量,您可能希望使用,这在一些JPa提供商中是可用的。但是请注意

我在J2EE中使用EJB应用程序:Cart有一个三层模型,它有许多行项目,每个行项目都有许多书(书不一定指行项目,它不是双向的)

标准JPA提供了一个标签,它标记了一个急切地获取的关系,就好像它是通过注释标记为急切的一样。在您的情况下,只需
加入fetch
行项目
,因为
书籍
将在单个查询中急切地加载每个
行项目

在JPA2.1中,您可以使用-您不需要修改查询,只需在查询中附加一个描述符,定义应该急切获取哪些关系


如果您希望优化到尽可能少的查询量,您可能希望使用,这在一些JPa提供商中是可用的。但是请注意,没有标准化的方法来启用此功能-我只是链接了如何使用EclipseLink。

我们需要知道您的目标是哪个版本的EE(或实际上是JPA),以及您是否想要纯EE/JPA解决方案-或者是否可以为特定的JPA实现使用专有功能(如果是,是哪一个)。在hibernate中,使用
@Fetch(JOIN)
也可以实现同样的效果-这将始终使用JOIN加载关系,因此它总是很急切。但是一般来说,
join-fetch
是@OndrejM指出的方法。使用第一种“join-fetch”方法,它会导致每个顶级对象有多行(也就是说,当join发现购物车有多个结果时,它会复制行,而不会转换成一个有多行的购物车)。我不明白,您在哪个级别获得重复的行?如果希望单个查询检索实体及其集合中的所有实体,则如果存在多个相关实体,则SQL结果中的记录必须包含重复的值。SQL结果是一个表而不是树,属于根实体的列总是具有相同的数据。我知道SQL结果是一个表,但如果ORM不知道如何克服这一点(并根据关系的需要过滤顶级记录和多个记录的单个记录),如果这不是ORM的内置功能,则不确定“join fetch”真的很有用。我相信其他语言ORM也可以做到这一点。
Cart(1) <--> (M) LineItem (1) --> (M) Book 
@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 {
   ...
}
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)