新年快乐:)
我有一个使用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")})
如果我要请求其中一个,第二个还是要加载还是仅应请求才加载?可能是,我需要使用两个图吗?
最佳答案
根据JPA 2.1规范3.7.4:
允许持久性提供程序获取其他实体状态
超出获取图或负载图指定的范围。这是必需的,
但是,持久性提供程序获取由指定的所有状态
提取或加载图。
因此,实际上@NamedEntityGraph
仅保证应该紧急加载哪些字段,而不保证不应加载哪些字段。
因此,如果将@NamedEntityGraph
和user
一起使用,则持久性提供程序(例如,Hibernate)只能加载user
字段,或者可以同时加载user
和restaurant
字段。这取决于实现方式,不能保证。
请参见this休眠问题。
但是据我所知,Hibernate除了加载@NamedEntityGraph
中指定的内容外,仅加载简单的字段,而不加载惰性关联。
因此,如果您使用休眠模式,它应该可以工作。
但是,当然,您需要两个单独的@NamedEntityGraph
用于user
和restaurant
字段。
或者,您可以使用ad-hoc spring-data-jpa
的功能:
@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {
@EntityGraph(attributePaths = { "members" })
GroupInfo getByGroupName(String name);
}
使用此代码,您不再需要显式声明
@NamedEntityGraph
。您可以仅内联指定字段。关于java - Spring Data JPA中的延迟初始化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41420688/