0

Assume that I have 2 objects A and B One to One related and B is nested under A. B is Lazy initialized and proxied and also I have an Entity Graph to fetch B eagerly when loading A as follows.

@NamedEntityGraph(name = "subGraph",attributeNodes = {@NamedAttributeNode("sub")})
public class A{
    Integer id;
    String name;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id", insertable = false, updatable = false)
    B sub;
}


public class B {
    int id;
    String description;
}

Let us have a stream of A queried from database and we are trying to set a DTO object and add to a DTO list:

1. List<ADto> dtoList = new ArrayList<>();
2.
3. aRepository.streamAll().forEach(a -> {
4.    ADto dto = new ADto();
5.    dto.setName(a.getName());
6.    dto.setSub(a.getB());
7. })

My question is:

If an instance of A does not have B (I mean SQL query with LEFT OUTER JOIN because of Entity Graph returns null fields for B) line 6 performs a second SQL query to database like

SELECT proxy_b_1.id, proxy_b_1.description FROM b as proxy_b_1;

Actually we already know that instance B under that specific instance A does not have value. It is shown also on debug mode. But why it makes a second SQL query? How can I mitigate this? I mean If I make an entity graph query that is enough for me if nested B exists. If does not exist do not perform an extra query. How can I do that?

Denny
  • 11
  • 2
  • @OneToOne(fetch = FetchType.LAZY) does not do what you think it does, see https://stackoverflow.com/questions/1444227/making-a-onetoone-relation-lazy. You can work around this using bytecode enhancement or (simpler) with mapping B as a "singleton Set". – Kirinya Jul 02 '18 at 13:47

1 Answers1

0

Specify the entity graph at the repository method and type EntityGraphType.LOAD:

@Repository
public interface ARepository extends CrudRepository<A, Integer> {

  @EntityGraph(value = "subGraph", type = EntityGraphType.LOAD)
  List<A> streamAll();

}
Markus Pscheidt
  • 5,297
  • 4
  • 44
  • 63