Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA EntityGraph with different views using Spring

I have a Spring application. After login, I am invoking getUserByEmail() method.

I only need user and role data. Based on role I am going to display different views, Each view has different data and requiring different child entity of User.

Seems like I have to call getUserByEmail() with different child entity.

This is my partial code involving Entities:

EntityGraph(value = "withAddresses", type = EntityGraphType.FETCH)
public class User{
  public firstName;
  public lastName;

  @OneToMany(fetch = FetchType.LAZY)
  public List<Address> addresses

  @OneToMany(fetch = FetchType.LAZY)
  public List<Order> orders;             
 }

 public userRepository extend jPaRepository(User.class,Long){
  @EntityGraph(name="withAdresses")
  getUserByEmail(String email)

  /* if possible */
  @EntityGraph(name="withOrder")
  getUserByEmail(String email)
 }
  1. Is it possible to have two graph of User objects with same query name? Because I need different data for different views.

  2. Also, when switching to a new view (new call in spring controller), transaction from previous view will be closed already and I have to make new call to have different data with user. I don't understand how fetch lazy is helpful if you are not in same transaction service method, unless I am not missing something.

For example if I need order data in "orderWiew.html" lazy load of order is not going to help I have to make another full call to same user data and additional Order data

like image 585
smile Avatar asked Jul 04 '15 04:07

smile


1 Answers

Just a sugestion about using multiple entity graphs: where I work we used the fact Spring Data can use multiple prefixes for query methods. We set a convention that methods with different prefixes have different entity graphs. So, for example, findUserByEmail(String) could use a more lazy graph than readUserByEmail(String).

Unfortunately I don't think Spring Data supports passing the entity graph to use in a dynamic way. You could implement it and have it added to your repository, though. To do that you should:

Create an interface that declares the new method (but does not extend JpaRepository or other repository interfaces)

public interface UserCustomOperations{
    User findUserByEmail(String email, String entityGraph);
}

Make your repository interface extend that interface.

public interface UserRepository extends JPaRepository<User,Long>, UserCustomOperations{
    // Not much to do here anymore
}

Create a class that implements your custom behaviour in the same package, with a suffix of Impl (by default).

public class  UserRepositoryImpl implements UserCustomOperations{
    public User findUserByEmail(String email, String entityGraph){
        // Inject the EntityManager and execute standard Jpa query with the entity graph set
    }
}
like image 117
Apokralipsa Avatar answered Oct 12 '22 19:10

Apokralipsa