1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[SQL] Hibernate 5: EntityGraph doesn't work with joins

Discussão em 'Outras Linguagens' iniciado por Stack, Novembro 8, 2024 às 11:32.

  1. Stack

    Stack Membro Participativo

    I'm having trouble using an EntityGraph to override lazy loading on some attributes.

    In the following examples Person.picture is annotated with @ManyToOne(fetch = FetchType.LAZY).

    If I just load entities of a single type without any joins, it is working perfectly.

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
    Root<Person> root = criteriaQuery.from(Person.class);
    criteriaQuery.select(root);

    TypedQuery<Person> typedQuery = this.entityManager.createQuery(query);
    EntityGraph<Person> entityGraph = entityManager.createEntityGraph(Person.class);
    entityGraph.addAttributeNodes("picture");
    query.setHint("javax.persistence.loadgraph", entityGraph);

    List<Person> result = typedQuery.getResultList();


    I see no proxies for Person.picture, but always the actual Picture object. I also can see in the generated SQL, that a JOIN is created for the table of Picture.

    But when I do some joins, the EntityGraph is accepted and also validated, but not applied for some reasons:

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
    Root<DepartmentMember> root = criteriaQuery.from(DepartmentMember.class);
    Join<DepartmentMember, Person> person = root.join("member", JoinType.INNER);
    Join<DepartmentMember, Department> department = root.join("department", JoinType.INNER);
    criteriaQuery.where(criteriaBuilder.equals(department.get("name"), "development"));
    criteriaQuery.select(person);

    TypedQuery<Person> typedQuery = this.entityManager.createQuery(query);
    EntityGraph<Person> entityGraph = entityManager.createEntityGraph(Person.class);
    entityGraph.addAttributeNodes("picture");
    query.setHint("javax.persistence.loadgraph", entityGraph);

    List<Person> result = typedQuery.getResultList();


    I get Person entities always having a proxy set for Person.picture. In the generated SQL query I only see the JOINs I defined, but no additional ones. The EntityGraph is definitely validated, because if I add some non-existing attributes, the whole thing will throw an error.

    I tried a different approach using fetch joins - which works. Like:

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
    Root<DepartmentMember> root = criteriaQuery.from(DepartmentMember.class);
    Join<DepartmentMember, Person> person = root.join("member", JoinType.INNER);
    person.fetch("picture");
    Join<DepartmentMember, Department> department = root.join("department", JoinType.INNER);
    criteriaQuery.where(criteriaBuilder.equals(department.get("name"), "development"));
    criteriaQuery.select(person);

    TypedQuery<Person> typedQuery = this.entityManager.createQuery(query);

    List<Person> result = typedQuery.getResultList();


    Here I can see a JOIN in the generated SQL and Person.picture has no proxy, but the actual object.

    Anyone aware what the reason could be why the EntityGraph is not working when joins are used? Anything wrong in my approach with EntityGraph?

    Continue reading...

Compartilhe esta Página