我有一个使用Hibernate和DataJPA的Spring MVC项目。
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "restaurant_id", nullable = false)
@NotNull
private Restaurant restaurant;
正如您所看到的,这里有两个带有急切提取的字段。我想让两个人都懒惰。我需要在这里使用@NamedEntityGraph
注释:
@NamedQueries({
@NamedQuery(name = Restaurant.GET_BY_ID, query = "SELECT r FROM Restaurant r WHERE r.id=?1"),
})
@Entity
@NamedEntityGraph(name = Restaurant.GRAPH_WITH_MENU_HISTORY, attributeNodes = {@NamedAttributeNode("menuHistory")})
@Table(name = "restaurants")
public class Restaurant extends NamedEntity {
@OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY, mappedBy = "restaurant")
@OrderBy(value = "date DESC")
private List<Dish> menuHistory;
public static final String GRAPH_WITH_MENU_HISTORY = "Restaurant.withMenuHistory";
我想知道,如果我要写
@NamedEntityGraph(name = "G_NAME", attributeNodes = {@NamedAttributeNode("user", "restaurant")})
如果我要求其中一个,无论如何第二次加载还是只能通过请求加载?可能是,我需要使用两个图表吗?
答案 0 :(得分:1)
根据JPA 2.1 Spec 3.7.4:
允许持久性提供程序获取其他实体状态 超出获取图或加载图指定的范围。这是必需的, 但是,持久性提供程序获取指定的所有状态 获取或加载图。
所以实际上@NamedEntityGraph
只保证应该急切加载哪些字段,而不是不应该加载哪些字段。
因此,如果您使用@NamedEntityGraph
生成user
,则您的持久性提供程序(例如Hibernate)只能加载user
字段或同时加载user
和restaurant
热切地。这取决于实施,不能保证。
请参阅this hibernate的问题。
但据我所知,除@NamedEntityGraph
中指定的Hibernate外,Hibernate只加载简单字段,而不加载延迟关联。
因此,如果您使用hibernate,它应该可以工作。
但是,对于@NamedEntityGraph
和user
字段,您需要两个单独的restaurant
。
或者您可以使用ad-hoc spring-data-jpa
的功能:
@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {
@EntityGraph(attributePaths = { "members" })
GroupInfo getByGroupName(String name);
}
使用此代码,您不再需要明确声明@NamedEntityGraph
。您只需指定内联字段即可。