Skip to content

Allow dynamic EntityGraph in repositories #2556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JordanDurieux opened this issue Jun 1, 2022 · 1 comment
Closed

Allow dynamic EntityGraph in repositories #2556

JordanDurieux opened this issue Jun 1, 2022 · 1 comment
Labels
status: duplicate A duplicate of another issue

Comments

@JordanDurieux
Copy link

JordanDurieux commented Jun 1, 2022

At the moment you have to write X times the same JPQL query if you want to have X different entitygraphs.

It would be great to enable dynamic EntityGraph with a special parameter in the repositories interfaces.

My suggestion would be to have a new special parameter (like Pageable and Sort) using JpaEntityGraph.
When this parameter is present, it would add the hint to the EntityManager with the entity graph to use.

Add a special parameter (handling the parameter index and so on) :

package org.springframework.data.repository.query;

public class Parameter {

	static final List<Class<?>> TYPES = Arrays.asList(Pageable.class, Sort.class, JpaEntityGraph.class);

[...]
}

In AbstractJpaQuery, add the hint to the query thanks to JpaParametersParameterAccessor :

    protected Query createQuery(JpaParametersParameterAccessor parameters) {
        return applyLockMode(applyEntityGraphConfiguration(applyHints(doCreateQuery(parameters), method), method, parameters), method);
    }

    private Query applyEntityGraphConfiguration(Query query, JpaQueryMethod method, JpaParametersParameterAccessor accessor) {

        if (method.getEntityGraph() != null && accessor.getJpaEntityGraph() != null) {
            throw new IllegalStateException("Cannot have EntityGraph annotation and JpaEntityGraph parameter at the same time!");
        }

        JpaEntityGraph entityGraph = method.getEntityGraph();

        if (entityGraph == null) {
            entityGraph = accessor.getJpaEntityGraph();
        }

        if (entityGraph != null) {
            Map<String, Object> hints = Jpa21Utils.tryGetFetchGraphHints(em, entityGraph , getQueryMethod().getEntityInformation().getJavaType());

            for (Map.Entry<String, Object> hint : hints.entrySet()) {
                query.setHint(hint.getKey(), hint.getValue());
            }
        }
        else if (entityGraphName != null) {
            // Maybe here use Jpa21Utils to make additional checks
            query.setHint(hint.getKey(), em.getEntityGraph(entityGraphName.getValue()));
        }

        return query;
    }

The usage in repositories would be :

public interface MyRepository extends JpaRepository<MyEntity, MyID> {

    @Query("...some jpql query...")
    List<MyEntity> findByMyProp(String myProp, JpaEntityGraph jpaEntityGraph);

}

Then we can use different entity graphs depending on the caller's context :

// Assuming we have a new JpaEntityGraph constructor with name only (defaulting the type to FETCH like the annotation)
myRepository.findByMyProp("something", new JpaEntityGraph("myentity-with-some-nodes"));
myRepository.findByMyProp("something", new JpaEntityGraph("myentity-with-other-nodes"));
@JordanDurieux JordanDurieux changed the title Enable dynamic NamedEntityGraph in repositories Allow dynamic NamedEntityGraph in repositories Jun 1, 2022
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 1, 2022
@JordanDurieux JordanDurieux changed the title Allow dynamic NamedEntityGraph in repositories Allow dynamic EntityGraph in repositories Jun 1, 2022
@schauder
Copy link
Contributor

schauder commented Jun 1, 2022

Duplicate of #951

@schauder schauder marked this as a duplicate of #951 Jun 1, 2022
@schauder schauder closed this as completed Jun 1, 2022
@schauder schauder added status: duplicate A duplicate of another issue and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

3 participants