1

I have two entities with one to many relationships:

public class User {
    @Id
    @GeneratedValue
    private Long id;
    private String username;
    private String phoneNumber;
    private Timestamp creationDate;
    @OneToMany(mappedBy = "user")
    private List<Role> roles;

}

public class Role {
    @Id
    @GeneratedValue
    private long id;
    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;

}

but when I call get method to load user information I can see in the log file that additional query to retrieve user's roles also called. How can I prevent it with spring data rest?

Alex
  • 1,940
  • 2
  • 18
  • 36
  • try setting fetchType as LAZY – pvpkiran Feb 26 '18 at 10:41
  • it doesn't work with spring-data-rest entities. Also fetchType is lazy by default. – Alex Feb 26 '18 at 10:43
  • the default lazy https://stackoverflow.com/questions/46684015/json-serializing-and-deserializing-with-hibernate-jpa-to-have-parent-object-into – Ali Akbarpour Feb 26 '18 at 10:52
  • What you have to shown is how you retrieve and manipulate the User entities. As a hint, enable the SQL logs you could see whether the query for the roles is performed in a second time – davidxxx Feb 26 '18 at 10:54
  • actually, I found that problem with show_sql property turned on, but thanks for advice. – Alex Feb 26 '18 at 10:55

2 Answers2

2

Define FetchType to LAZY as below.

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;

By default, JPA fetchType for ManyToOne is EAGER. Refer here

Ram
  • 1,743
  • 2
  • 18
  • 40
  • I tried that approach and it didn't work. Actually, I loaded all users(not roles) so not sure how the mapping of child entity will fix that... – Alex Feb 26 '18 at 11:04
1

Since you are using SDR, to prevent Roles from loading when you get Users you can:

1) Create repository for Roles. If you had one check if it exported (@RepositoryRestResource(exported = true) - by default just add this annotation without this parameter).

2) Or make User projection without roles:

@Projection(name = "justUser", types = User.class)
public interface JustUser {
    String getUsername();
    String getPhoneNumber();
    Timestamp getCreationDate();
}

Then use it in your request, like this:

GET /users?projection=justUser
Cepr0
  • 28,144
  • 8
  • 75
  • 101