0

happy new year:)

I have a Spring MVC project using Hibernate and DataJPA.

@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;

As you can see, here is two fields with eager fetch. I want to make both a lazy. I need to user @NamedEntityGraph annotation asI made here:

    @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";

I want to know, if I'll write

@NamedEntityGraph(name = "G_NAME", attributeNodes = {@NamedAttributeNode("user", "restaurant")})

and if I'll request one of them, will the second load anyway or it will load only by request to him? May be, I need to user two graphs?

6
  • "if I'll request one of them" - one of what? "will the second load anyway" - what will load anyway? "or it will load only by request to him" - to who? :) Make question more explicit. Commented Jan 2, 2017 at 2:15
  • @djxak I mean class fields "user" and "restaurant" :)
    – Nicolazz92
    Commented Jan 2, 2017 at 2:34
  • How you would to query the entity consisting the user and restaurant fields? Where is your repository code? Commented Jan 2, 2017 at 2:39
  • @djxak I didn't write this part yet, but here is a my code from another class with one lazy field, I'll do it similarly:
    – Nicolazz92
    Commented Jan 2, 2017 at 2:43
  • @djxak, @NamedQuery(name = User.GET_BY_ID, query = "SELECT u FROM User u WHERE u.id=?1")
    – Nicolazz92
    Commented Jan 2, 2017 at 2:56

1 Answer 1

1

According to JPA 2.1 Spec 3.7.4:

The persistence provider is permitted to fetch additional entity state beyond that specified by a fetch graph or load graph. It is required, however, that the persistence provider fetch all state specified by the fetch or load graph.

So actually the @NamedEntityGraph just guarantees what fields should be eagerly loaded, but not what fields should not be loaded.

So, if you make @NamedEntityGraph with user, your persistence provider (Hibernate for example) can load only user field or both user and restaurant fields eagerly. This is dependent on implementation and not guaranteed.

See this hibernate's issue.

But as far as I know, the Hibernate loads only simple fields in addition to specified in @NamedEntityGraph, and not loads lazy associations.

So if you use hibernate, it should work.

But of course you need two separate @NamedEntityGraphs for user and restaurant fields.

Or you can use ad-hoc spring-data-jpa's feature:

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

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

}

With this code you don't need explicitly declare @NamedEntityGraph anymore. You can just specify fields inline.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.