{"id":25932763,"url":"https://github.com/cosium/spring-data-jpa-entity-graph","last_synced_at":"2025-05-14T18:05:52.671Z","repository":{"id":13458990,"uuid":"74491626","full_name":"Cosium/spring-data-jpa-entity-graph","owner":"Cosium","description":"Spring Data JPA extension allowing full dynamic usage of EntityGraph on repositories","archived":false,"fork":false,"pushed_at":"2025-04-21T00:23:24.000Z","size":625,"stargazers_count":505,"open_issues_count":9,"forks_count":49,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-05-08T09:05:36.649Z","etag":null,"topics":["entity-graph","jpa","orm","spring-data","spring-data-jpa"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Cosium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-22T16:27:12.000Z","updated_at":"2025-05-01T11:48:51.000Z","dependencies_parsed_at":"2023-01-13T17:28:44.963Z","dependency_job_id":"654c6418-e187-403b-a4da-fd1a60e7384f","html_url":"https://github.com/Cosium/spring-data-jpa-entity-graph","commit_stats":null,"previous_names":[],"tags_count":66,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cosium%2Fspring-data-jpa-entity-graph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cosium%2Fspring-data-jpa-entity-graph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cosium%2Fspring-data-jpa-entity-graph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cosium%2Fspring-data-jpa-entity-graph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Cosium","download_url":"https://codeload.github.com/Cosium/spring-data-jpa-entity-graph/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198514,"owners_count":22030965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["entity-graph","jpa","orm","spring-data","spring-data-jpa"],"created_at":"2025-03-04T00:39:05.063Z","updated_at":"2025-05-14T18:05:47.662Z","avatar_url":"https://github.com/Cosium.png","language":"Java","readme":"[![Build Status](https://github.com/Cosium/spring-data-jpa-entity-graph/actions/workflows/ci.yml/badge.svg)](https://github.com/Cosium/spring-data-jpa-entity-graph/actions/workflows/ci.yml)\n[![Maven Central](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)\n\n# Spring Data JPA EntityGraph\n\n[Spring Data JPA](https://github.com/spring-projects/spring-data-jpa) only supports `EntityGraph` through annotations.  \nThus, for a repository method, you must select at most one `EntityGraph` before compilation.  \nThis prevents you from choosing the best `EntityGraph` considering the runtime context :broken_heart:\n\n[Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) allows you to choose `EntityGraph` at runtime! This choice is elegantly made by passing `EntityGraph`, as an argument, to any Spring Data JPA repository method :heart_eyes:\n\n# Quick start\n1. Select the correct version from the [compatibility matrix](#compatibility-matrix)\n2. In addition to [Spring Data JPA](https://github.com/spring-projects/spring-data-jpa), add [Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) dependency :\n\n    ```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.cosium.spring.data\u003c/groupId\u003e\n      \u003cartifactId\u003espring-data-jpa-entity-graph\u003c/artifactId\u003e\n      \u003cversion\u003e${spring-data-jpa-entity-graph.version}\u003c/version\u003e\n    \u003c/dependency\u003e\n    ```\n3. Set the repository factory bean class to `EntityGraphJpaRepositoryFactoryBean` :\n\n    ```java\n    @SpringBootApplication\n    @EnableJpaRepositories(repositoryFactoryBeanClass = EntityGraphJpaRepositoryFactoryBean.class)\n    public class App {\n        //...\n    }\n    ```\n\n# 2.x to 3.x breaking changes\n\n- Moved from Java 8 to 17 as the source language\n- `javax.persistence` replaced by `jakarta.persistence`\n- `com.cosium.spring.data.jpa.entity.graph.domain` classes (deprecated in 2.7.x) have been removed in favor of `com.cosium.spring.data.jpa.entity.graph.domain2`\n- `Default EntityGraph by name pattern` feature (deprecated in 2.7.x) has been removed. `*.default` named EntityGraph are not considered as default EntityGraph anymore. Please read [default EntityGraph](#repository-default-entitygraph) to use the new `Default EntityGraph` feature instead.\n\n# Usage\n\n## On custom repository methods\n\nIf you want to define a custom repository method accepting an `EntityGraph`, just do it™.\n\nFor example, given an entity having attribute named `label` of type String, you could declare and use a repository like this:\n\n```java\ninterface MyRepository extends Repository\u003cMyEntity, Long\u003e {\n\tOptional\u003cMyEntity\u003e findByLabel(String label, EntityGraph entityGraph);\n}\n```\n```java\nmyRepository.findByLabel(\"foo\", NamedEntityGraph.loading(\"bar\"));\n```\n\n## On pre-defined repository methods\n\n[Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) provides repository interfaces extending [Spring Data JPA](https://github.com/spring-projects/spring-data-jpa). For each [Spring Data JPA](https://github.com/spring-projects/spring-data-jpa) pre-defined method, the provided interfaces overload the method with `EntityGraph` as an additional argument.\n\nFor example, [Spring Data JPA](https://github.com/spring-projects/spring-data-jpa) `CrudRepository` defines method `Optional\u003cT\u003e findById(ID id)`. This method is overloaded by [Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) `EntityGraphCrudRepository` as `Optional\u003cT\u003e findById(ID id, EntityGraph entityGraph)`.\n\nTo be able to use these overloaded methods, you must extend one of [Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) provided repository interfaces.\n\nThe following matrix describes the mapping between [Spring Data JPA](https://github.com/spring-projects/spring-data-jpa) and [Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) :\n\n| [Spring Data JPA](https://github.com/spring-projects/spring-data-jpa) | [Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) |\n|-----------------------------------------------------------------------|---------------------------------------------------------------------------------------|\n| JpaRepository                                                         | EntityGraphJpaRepository                                                              |\n| JpaSpecificationExecutor                                              | EntityGraphJpaSpecificationExecutor                                                   |\n| QuerydslPredicateExecutor                                             | EntityGraphQuerydslPredicateExecutor                                                  |\n| CrudRepository                                                        | EntityGraphCrudRepository                                                             |\n| PagingAndSortingRepository                                            | EntityGraphPagingAndSortingRepository                                                 |\n| QueryByExampleExecutor                                                | EntityGraphQueryByExampleExecutor                                                     |\n\nFor example, if you wanted to use `Optional\u003cT\u003e findById(ID id, EntityGraph entityGraph)`, you could declare and use your repository like this:\n\n```java\ninterface MyRepository extends EntityGraphCrudRepository\u003cMyEntity, Long\u003e {\n}\n```\n```java\nmyRepository.findById(1L, NamedEntityGraph.loading(\"foo\"));\n```\n\n## EntityGraph provided implementations\n\n### DynamicEntityGraph\n\n`DynamicEntityGraph` class allows you to create on-the-fly `EntityGraph` by defining their attribute paths. This is similar to [Spring's ad-hoc attribute paths](http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods.query-property-expressions).\n\nFor example, let's consider the following entities :\n```java\n@Entity\nclass Maker {\n   //...\n   @OneToOne(fetch = FetchType.LAZY)\n   private Address address;\n   //...\n}\n```\n```java\n@Entity\nclass Product {\n    @Id\n    private long id = 0;\n    private String name;\n    @ManyToOne(fetch = FetchType.LAZY)\n    private Brand brand;\n    @ManyToOne(fetch = FetchType.LAZY)\n    private Maker maker;\n    //...\n}\t\n```\n\nYou could declare the following repository :\n```java\npublic interface MyRepository extends Repository\u003cProduct, Long\u003e {\n    List\u003cProduct\u003e findByName(String name, EntityGraph entityGraph);\n}\n```\n\nThen perform the `findByName` using ad-hoc `product(brand, maker(address))` `EntityGraph` :\n```java\nmyRepository.findById(1L, DynamicEntityGraph.loading().addPath(\"brand\").addPath(\"maker\", \"address\").build());\n```\n\n### NamedEntityGraph\n\n`NamedEntityGraph` class allows you to reference an `EntityGraph` by its name. Such `EntityGraph` must have beforehand been registered through `EntityManager#createEntityGraph(String graphName)` or declared using `@NamedEntityGraph` annotation.\n\nFor example, let's consider the following entity :\n```java\n@NamedEntityGraphs(value = {\n    @NamedEntityGraph(name = \"productBrand\", attributeNodes = {\n        @NamedAttributeNode(\"brand\")\n    })\n})\n@Entity\npublic class Product {\n    @Id\n    private long id = 0;\n    private String name;\n    @ManyToOne(fetch = FetchType.LAZY)\n    private Brand brand;\n    //...\n}\t\n```\n\nYou could declare the following repository :\n```java\npublic interface MyRepository extends Repository\u003cProduct, Long\u003e {\n    List\u003cProduct\u003e findByName(String name, EntityGraph entityGraph);\n}\n```\n\nThen perform the `findByName` query using `productBrand` named `EntityGraph` like this :\n```java\nmyRepository.findByName(\"foo\", NamedEntityGraph.loading(\"productBrand\"));\n```\n\n### Type safe EntityGraph\n\nComposing entity graphs by hand can be tedious and error-prone. Wouldn't it be great to benefit from autocompletion and strong type checking while composing your entity graph?\n\n[Spring Data JPA EntityGraph Generator](https://github.com/Cosium/spring-data-jpa-entity-graph) has you covered.\n\nThis annotation processor makes use of the JPA metamodel information (part of JPA specification) generated by the tool of your choice (e.g. `hibernate-jpamodelgen`) to generate `EntityGraph` composers allowing you to safely and easily compose `EntityGraph` at runtime.\n\nYou need to add:\n- A JPA metamodel information generator. `hibernate-jpamodelgen` is great and should be compatible with any JPA ORM.\n- The entity graph generator annotation processor dependency.\n\nYour `pom.xml` should look like this:\n```xml\n\u003cbuild\u003e\n   \u003cplugins\u003e\n      \u003cplugin\u003e\n         \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n         \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n         \u003cconfiguration\u003e\n            \u003cannotationProcessorPaths\u003e\n               \u003cpath\u003e\n                  \u003cgroupId\u003eorg.hibernate.orm\u003c/groupId\u003e\n                  \u003cartifactId\u003ehibernate-jpamodelgen\u003c/artifactId\u003e\n                  \u003cversion\u003e${hibernate-jpamodelgen.version}\u003c/version\u003e\n               \u003c/path\u003e\n               \u003cpath\u003e\n                  \u003cgroupId\u003ecom.cosium.spring.data\u003c/groupId\u003e\n                  \u003cartifactId\u003espring-data-jpa-entity-graph-generator\u003c/artifactId\u003e\n                  \u003cversion\u003e${spring-data-jpa-entity-graph.version}\u003c/version\u003e\n               \u003c/path\u003e\n            \u003c/annotationProcessorPaths\u003e\n         \u003c/configuration\u003e\n      \u003c/plugin\u003e\n   \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\nAfter compiling your project, you should find `XEntityGraph` classes where `X` is the name of your Entity. \n\nFor example, let's consider the following entity :\n```java\n@Entity\npublic class Product {\n    @Id\n    private long id = 0;\n    private String name;\n    @ManyToOne(fetch = FetchType.LAZY)\n    private Brand brand;\n    //...\n}\t\n```\nYou could declare the following repository :\n```java\npublic interface MyRepository extends Repository\u003cProduct, Long\u003e {\n    List\u003cProduct\u003e findByName(String name, EntityGraph entityGraph);\n}\n```\n\n`spring-data-jpa-entity-graph-generator` will detect `Product` and generate in return `ProductEntityGraph` class.\nYou could then perform the `findByName` query using `product(brand, maker(address))` `EntityGraph` like this :\n\n```java\nproductRepository.findById(1L, ProductEntityGraph\n                               .____()\n                               .brand()\n                               .____\n                               .maker()\n                               .address()\n                               .____\n                               .____());\n```\n\n## Repository default EntityGraph\n\nYou can declare at most one `default EntityGraph` per repository by overriding `EntityGraphRepository#defaultEntityGraph` method. \n\nCalling **any** repository query method - custom or pre-defined - without `EntityGraph` or with an `EntityGraph#NOOP` equivalent will lead to the `default EntityGraph` usage. Otherwise, the `EntityGraph` passed as query method argument will always have priority.\n\nYou could declare a repository as follows :\n```java\ninterface MyRepository extends EntityGraphCrudRepository\u003cMyEntity, Long\u003e {\n  @Override\n  default Optional\u003cEntityGraph\u003e defaultEntityGraph() {\n    return NamedEntityGraph.loading(\"foo\").execute(Optional::of);\n  } \n  \n  List\u003cMyEntity\u003e findByName(String name);\n  List\u003cMyEntity\u003e findByName(String name, EntityGraph entityGraph);\n}\n```\n\nThe following snippets will lead to the `default EntityGraph` usage:\n```java\nmyRepository.findById(1L);\n```\n```java\nmyRepository.findById(1L, EntityGraph.NOOP);\n```\n```java\nmyRepository.findByName(\"bar\");\n```\n\nThe following snippets will ignore the `default EntityGraph` and instead use the `EntityGraph` passed as argument:\n```java\nmyRepository.findById(1L, NamedEntityGraph.loading(\"alice\"));\n```\n```java\nmyRepository.findByName(\"bar\", NamedEntityGraph.loading(\"barry\"));\n```\n\n## Chaining EntityGraph definition with query execution\n\nIf you prefer fluent apis, you can use any instance of `EntityGraph` like this:\n\n```java\nList\u003cProduct\u003e products = ProductEntityGraph\n                          .____()\n                          .brand()\n                          .____\n                          .maker()\n                          .address()\n                          .____\n                          .____()\n                          .execute(entityGraph -\u003e myRepository.findByLabel(\"foo\", entityGraph));\n```\n\n## EntityGraph Semantics\n\nJPA 2.1 defines 2 semantics:\n* [Load Graph Semantics](https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf)\n* [Fetch Graph Semantics](https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf)\n\n[Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) uses [Load Graph Semantics](https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf) as the default semantic. This means if you don't define a semantic, `EntityGraph` implementations will be built using [Load Graph Semantics](https://download.oracle.com/otn-pub/jcp/persistence-2_1-fr-eval-spec/JavaPersistence.pdf).\n\nEach provided `EntityGraph` implementation provides an easy way to select the `Graph Semantics`.\n\n# Demo\n\nYou can play with https://github.com/Cosium/spring-data-jpa-entity-graph-sample to see the extension in action in a simple Spring Application.\n\n# Compatibility matrix\n\n| [Spring Data JPA](https://github.com/spring-projects/spring-data-jpa) version | [Spring Data JPA EntityGraph](https://github.com/Cosium/spring-data-jpa-entity-graph) version                                                                                                                                                                |\n|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| 3.2.1+                                                                        | [![Maven Central 3.2.2+](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/3.2.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)                                                                                                                                                                                                                                                             |\n| 3.2.0                                                                         | [![Maven Central 3.2.1](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/3.2.1.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22) |\n| 3.1.x                                                                         | [![Maven Central 3.1.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/3.1.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 3.0.x                                                                         | [![Maven Central 3.0.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/3.0.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.7.x                                                                         | [![Maven Central 2.7.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.7.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.6.x                                                                         | [![Maven Central 2.6.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.6.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.5.x                                                                         | [![Maven Central 2.5.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.5.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.4.x                                                                         | [![Maven Central 2.4.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.4.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.3.x                                                                         | [![Maven Central 2.3.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.3.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.2.x                                                                         | [![Maven Central 2.2.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.2.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.1.x                                                                         | [![Maven Central 2.1.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.1.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 2.0.x                                                                         | [![Maven Central 2.0.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/2.0.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22)   |\n| 1.11.x                                                                        | [![Maven Central 1.11.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/1.11.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22) |\n| 1.10.x                                                                        | [![Maven Central 1.10.x](https://img.shields.io/maven-central/v/com.cosium.spring.data/spring-data-jpa-entity-graph/1.10.svg)](https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.cosium.spring.data%22%20AND%20a%3A%22spring-data-jpa-entity-graph%22) |\n\nFor example, if you were using `spring-data-jpa 2.2.x` in your project, you would need to select any `spring-data-jpa-entity-graph 2.2.x`. Thus `spring-data-jpa-entity-graph 2.2.8` would be eligible.\n\n# \"Making JPA Great Again\" talk\n\nThis talk was given at Paris JUG in January 2019.  \n\nThe [slides](https://cosium.github.io/making-jpa-great-again/) are in english.  \nThe video is in French:  \n[![Alt text](https://img.youtube.com/vi/7yZgSdkvJDE/0.jpg)](https://www.youtube.com/watch?v=7yZgSdkvJDE)\n\n# Genesis\n\nThis project was created following https://github.com/spring-projects/spring-data-jpa/issues/1120 discussion.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcosium%2Fspring-data-jpa-entity-graph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcosium%2Fspring-data-jpa-entity-graph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcosium%2Fspring-data-jpa-entity-graph/lists"}