2017-01-02 90 views
0

新年快乐:)春季初始化DataJPA

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

“如果我要求其中之一” - 其中之一? “无论如何将第二次加载” - 反正会加载什么? “或者只会按照他的要求加载” - 给谁? :)更明确地提出问题。 – djxak

+0

@djxak我的意思是类字段“user”和“restaurant”:) – Nicolazz92

+0

如何查询包含'user'和'restaurant'字段的实体?你的* repository *代码在哪里? – djxak

回答

0

根据JPA 2.1规格3.7.4:

的持久性提供允许读取附加实体状态 超过由一个取图表或负载图形指定。然而,要求, 持久性提供者获取 指定的获取或加载图的所有状态。

所以实际上@NamedEntityGraph只是保证什么领域应该急切加载,但不应该加载哪些领域。

所以,如果你让@NamedEntityGraphuser,您的持久性提供者(Hibernate的举例)可以加载只user场或两者userrestaurant领域的热切。这取决于实施,不保证。

请参阅this hibernate的问题。

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

所以,如果你使用休眠,它应该工作。

但当然你需要两个单独的@NamedEntityGraph s为userrestaurant字段。

或者你可以使用ad-hocspring-data-jpa的特点:

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

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

} 

有了这个代码,你并不需要显式声明@NamedEntityGraph了。您可以直接指定内联字段。

+0

非常感谢! – Nicolazz92