Spring DataJPA中的延迟初始化

时间:2017-01-02 02:10:41

标签: java hibernate spring-mvc spring-data-jpa lazy-loading

新年快乐:)

我有一个使用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")})

如果我要求其中一个,无论如何第二次加载还是只能通过请求加载?可能是,我需要使用两个图表吗?

1 个答案:

答案 0 :(得分:1)

根据JPA 2.1 Spec 3.7.4:

  

允许持久性提供程序获取其他实体状态   超出获取图或加载图指定的范围。这是必需的,   但是,持久性提供程序获取指定的所有状态   获取或加载图。

所以实际上@NamedEntityGraph只保证应该急切加载哪些字段,而不是不应该加载哪些字段。

因此,如果您使用@NamedEntityGraph生成user,则您的持久性提供程序(例如Hibernate)只能加载user字段或同时加载userrestaurant热切地。这取决于实施,不能保证。

请参阅this hibernate的问题。

但据我所知,除@NamedEntityGraph中指定的Hibernate外,Hibernate只加载简单字段,而不加载延迟关联。

因此,如果您使用hibernate,它应该可以工作。

但是,对于@NamedEntityGraphuser字段,您需要两个单独的restaurant

或者您可以使用ad-hoc spring-data-jpa的功能:

@Repository
public interface GroupRepository extends CrudRepository<GroupInfo, String> {

  @EntityGraph(attributePaths = { "members" })
  GroupInfo getByGroupName(String name);

}

使用此代码,您不再需要明确声明@NamedEntityGraph。您只需指定内联字段即可。