新年快乐:)

我有一个使用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仅保证应该紧急加载哪些字段,而不保证不应加载哪些字段。

因此,如果将@NamedEntityGraphuser一起使用,则持久性提供程序(例如,Hibernate)只能加载user字段,或者可以同时加载userrestaurant字段。这取决于实现方式,不能保证。

请参见this休眠问题。

但是据我所知,Hibernate除了加载@NamedEntityGraph中指定的内容外,仅加载简单的字段,而不加载惰性关联。

因此,如果您使用休眠模式,它应该可以工作。

但是,当然,您需要两个单独的@NamedEntityGraph用于userrestaurant字段。

或者,您可以使用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/

10-13 00:34