0

I know you can control fetching behaviour using @javax.persistence.FetchType, however can you control the fetching programmatically from within a JPA Criteria query? Basically I can tell from the query what part of the application is likely calling and what part of the model will (most likely) be needed.

I couldn't find an answer in any of the tutorials but these old questions:


tl;dr: can you control the fetching programmatically from within a JPA Criteria query?

Community
  • 1
  • 1
Sled
  • 18,541
  • 27
  • 119
  • 168

1 Answers1

2

You can use entity graphs for this (which works with JPQL and Criteria API).

Example:

@Entity
@NamedEntityGraph(name = "User.withRoles", attributeNodes = {
    @NamedAttributeNode("roles") // fetch "roles" eager
})
@NamedQuery(name = "User.byName", query = "SELECT u FROM User u WHERE u.name = :name")
public class User {
    /* ... */

    @Column(updatable = false)
    private String name;

    @ManyToMany // fetch lazy by default
    @JoinTable(name = "user_role", /* ... */)
    private Set<Role> roles;
}

public User getUser(String name, boolean withRoles) {
    TypedQuery<User> query = entityManager.createNamedQuery("User.byName", User.class);
    if (withRoles) {
        EntityGraph<User> loadGraph = (EntityGraph<User>) entityManager.createEntityGraph("User.withRoles");
        query.setHint("javax.persistence.loadgraph", loadGraph);
    }

    try {
        return query.setParameter("name", name).getSingleResult();
    } catch (NoResultException ex) {
        return null;
    }
}

Similarly you can also use a fetch graph to exclude fields from being fetched.

jabu.10245
  • 1,884
  • 1
  • 11
  • 20