diff --git a/.travis.yml b/.travis.yml
index 04a8a56..0ae010d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,6 @@ language: java
 jdk:
   - oraclejdk11
 before_install:
-  - curl -o $HOME/.m2/settings.xml https://raw.githubusercontent.com/Cosium/spring-data-jpa-entity-graph/$TRAVIS_BRANCH/src/site/resources/settings.xml
+  - curl -o $HOME/.m2/settings.xml https://raw.githubusercontent.com/Cosium/spring-data-jpa-entity-graph/$TRAVIS_BRANCH/site/settings.xml
 after_success:
-  - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
+  - bash <(curl -s https://codecov.io/bash)
diff --git a/README.md b/README.md
index 5090b47..dcf2327 100644
--- a/README.md
+++ b/README.md
@@ -21,13 +21,24 @@ This prevents you from choosing the best EntityGraph considering the runtime con
 Thanks to [spring-data-jpa-entity-graph](https://github.com/Cosium/spring-data-jpa-entity-graph), you can choose EntityGraph at runtime!  
 This choice is elegantly made by passing EntityGraph, as an argument, to any Spring Data JPA repository method :heart_eyes:
 
-Example:
 ```java
 // This will apply 'Product.brand' named EntityGraph to findByLabel
 productRepository.findByLabel("foo", EntityGraphs.named("Product.brand"));
 
-// This will apply 'Product.supplier' named EntityGraph to findByLabel
-productRepository.findByLabel("foo", EntityGraphs.named("Product.supplier"));
+// This will apply "product(brand, category, maker(country))" dynamic entity graph findByLabel
+productRepository.findByLabel(
+            "foo", 
+            // ProductEntityGraph was generated at compilation time
+            ProductEntityGraph.____()
+                              .brand()
+                              .____
+                              .category()
+                              .____
+                              .maker()
+                              .country()
+                              .____
+                              .____()
+);
 ```
 
 Now run to the documentation !
diff --git a/core/pom.xml b/core/pom.xml
new file mode 100644
index 0000000..4d311ba
--- /dev/null
+++ b/core/pom.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.cosium.spring.data</groupId>
+    <artifactId>spring-data-jpa-entity-graph-parent</artifactId>
+    <version>2.2.9-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>spring-data-jpa-entity-graph</artifactId>
+
+  <properties>
+    <spring.data.jpa>2.2.6.RELEASE</spring.data.jpa>
+    <eclipselink>2.6.8</eclipselink>
+    <querydsl>4.2.1</querydsl>
+
+    <!--Test-->
+    <dbunit>2.5.3</dbunit>
+    <spring-test-dbunit>1.3.0</spring-test-dbunit>
+    <spring.framework.version>5.2.5.RELEASE</spring.framework.version>
+    <hibernate.version>5.4.13.Final</hibernate.version>
+    <hsqldb.version>2.3.4</hsqldb.version>
+    <assertj>3.8.0</assertj>
+    <logback>1.2.3</logback>
+
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <!--Needed by SpringHibernateJpaPersistenceProvider for spring-data-jpa while building with JDK 11-->
+      <groupId>javax.xml.bind</groupId>
+      <artifactId>jaxb-api</artifactId>
+      <version>2.3.0</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.data</groupId>
+      <artifactId>spring-data-jpa</artifactId>
+      <version>${spring.data.jpa}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.persistence</groupId>
+      <artifactId>org.eclipse.persistence.jpa</artifactId>
+      <version>${eclipselink}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
+      <!--Needed by querydsl for @Generated annotation-->
+      <groupId>javax.annotation</groupId>
+      <artifactId>javax.annotation-api</artifactId>
+      <version>1.3.2</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.querydsl</groupId>
+      <artifactId>querydsl-apt</artifactId>
+      <version>${querydsl}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.hibernate</groupId>
+      <artifactId>hibernate-jpamodelgen</artifactId>
+      <version>${hibernate.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>spring-data-jpa-entity-graph-generator</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.querydsl</groupId>
+      <artifactId>querydsl-jpa</artifactId>
+      <version>${querydsl}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <!--Test-->
+    <dependency>
+      <groupId>org.hsqldb</groupId>
+      <artifactId>hsqldb</artifactId>
+      <version>${hsqldb.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hibernate</groupId>
+      <artifactId>hibernate-entitymanager</artifactId>
+      <version>${hibernate.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.github.springtestdbunit</groupId>
+      <artifactId>spring-test-dbunit</artifactId>
+      <version>${spring-test-dbunit}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-test</artifactId>
+      <version>${spring.framework.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.dbunit</groupId>
+      <artifactId>dbunit</artifactId>
+      <version>${dbunit}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>${assertj}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <version>${logback}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>com.mysema.maven</groupId>
+        <artifactId>apt-maven-plugin</artifactId>
+        <version>1.1.3</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-process</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>target/generated-test-sources/test-annotations</outputDirectory>
+              <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>3.1.0</version>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.cosium.spring.data.jpa.entity.graph.core</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/AbstractEntityGraph.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/AbstractEntityGraph.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/AbstractEntityGraph.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/AbstractEntityGraph.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraph.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraph.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraph.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraph.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraph.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraph.java
similarity index 83%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraph.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraph.java
index db5b48d..091cd70 100644
--- a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraph.java
+++ b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraph.java
@@ -20,8 +20,7 @@ public interface EntityGraph {
 
   /**
    * @return True if the EntityGraph is optional.<br>
-   *     Passing an optional EntityGraph to an unsupported method will not trigger {@link
-   *     com.cosium.spring.data.jpa.entity.graph.repository.exception.InapplicableEntityGraphException}.
+   *     Passing an optional EntityGraph to an unsupported method will not fail.
    */
   boolean isOptional();
 }
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphType.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphType.java
similarity index 88%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphType.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphType.java
index 6aa428d..6a74fbe 100644
--- a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphType.java
+++ b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphType.java
@@ -11,7 +11,7 @@ public enum EntityGraphType {
 
   private final String key;
 
-  private EntityGraphType(String value) {
+  EntityGraphType(String value) {
     this.key = value;
   }
 
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphUtils.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphUtils.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphUtils.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphUtils.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphs.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphs.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphs.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphs.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraph.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraph.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraph.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraph.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraph.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraph.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraph.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraph.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCrudRepository.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCrudRepository.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCrudRepository.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCrudRepository.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepository.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepository.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepository.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepository.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutor.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutor.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutor.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutor.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphPagingAndSortingRepository.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphPagingAndSortingRepository.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphPagingAndSortingRepository.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphPagingAndSortingRepository.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQueryByExampleExecutor.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQueryByExampleExecutor.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQueryByExampleExecutor.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQueryByExampleExecutor.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutor.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutor.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutor.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutor.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/InapplicableEntityGraphException.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/InapplicableEntityGraphException.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/InapplicableEntityGraphException.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/InapplicableEntityGraphException.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleDefaultEntityGraphException.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleDefaultEntityGraphException.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleDefaultEntityGraphException.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleDefaultEntityGraphException.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleEntityGraphException.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleEntityGraphException.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleEntityGraphException.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/MultipleEntityGraphException.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/RepositoryEntityGraphException.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/RepositoryEntityGraphException.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/RepositoryEntityGraphException.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/exception/RepositoryEntityGraphException.java
diff --git a/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaParameters.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaParameters.java
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaParameters.java
@@ -0,0 +1 @@
+
diff --git a/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaQueryMethod.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaQueryMethod.java
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaQueryMethod.java
@@ -0,0 +1 @@
+
diff --git a/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaQueryMethodFactory.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaQueryMethodFactory.java
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/query/EntityGraphAwareJpaQueryMethodFactory.java
@@ -0,0 +1 @@
+
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/CountQueryDetector.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/CountQueryDetector.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/CountQueryDetector.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/CountQueryDetector.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphAwareQuerydslJpaRepository.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphAwareQuerydslJpaRepository.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphAwareQuerydslJpaRepository.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphAwareQuerydslJpaRepository.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphBean.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphBean.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphBean.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphBean.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactory.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactory.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactory.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactory.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactoryBean.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactoryBean.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactoryBean.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphJpaRepositoryFactoryBean.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepository.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepository.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepository.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepository.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphSimpleJpaRepository.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphSimpleJpaRepository.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphSimpleJpaRepository.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphSimpleJpaRepository.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/QueryHintsUtils.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/QueryHintsUtils.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/QueryHintsUtils.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/QueryHintsUtils.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryEntityManagerEntityGraphInjector.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryEntityManagerEntityGraphInjector.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryEntityManagerEntityGraphInjector.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryEntityManagerEntityGraphInjector.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryMethodEntityGraphExtractor.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryMethodEntityGraphExtractor.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryMethodEntityGraphExtractor.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryMethodEntityGraphExtractor.java
diff --git a/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryQueryEntityGraphInjector.java b/core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryQueryEntityGraphInjector.java
similarity index 100%
rename from src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryQueryEntityGraphInjector.java
rename to core/src/main/java/com/cosium/spring/data/jpa/entity/graph/repository/support/RepositoryQueryEntityGraphInjector.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/BaseTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/BaseTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/BaseTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/BaseTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/DataRepositoryConfiguration.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/DataRepositoryConfiguration.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/DataRepositoryConfiguration.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/DataRepositoryConfiguration.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraphTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraphTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraphTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/DynamicEntityGraphTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphsTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphsTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphsTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/EntityGraphsTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraphTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraphTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraphTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/NamedEntityGraphTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraphTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraphTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraphTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/domain/OptionalEntityGraphTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCustomJpaRepositoryTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCustomJpaRepositoryTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCustomJpaRepositoryTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphCustomJpaRepositoryTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepositoryTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepositoryTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepositoryTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaRepositoryTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutorTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutorTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutorTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphJpaSpecificationExecutorTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutorTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutorTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutorTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/EntityGraphQuerydslPredicateExecutorTest.java
diff --git a/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/GeneratedEntityGraphTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/GeneratedEntityGraphTest.java
new file mode 100644
index 0000000..a268980
--- /dev/null
+++ b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/GeneratedEntityGraphTest.java
@@ -0,0 +1,50 @@
+package com.cosium.spring.data.jpa.entity.graph.repository;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.cosium.spring.data.jpa.entity.graph.BaseTest;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.Product;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.ProductEntityGraph;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.ProductRepository;
+import com.github.springtestdbunit.annotation.DatabaseSetup;
+import com.github.springtestdbunit.annotation.DatabaseTearDown;
+import javax.inject.Inject;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import org.hibernate.Hibernate;
+import org.junit.Test;
+import org.springframework.transaction.annotation.Transactional;
+
+/** @author Réda Housni Alaoui */
+@DatabaseSetup(BaseTest.DATASET)
+@DatabaseTearDown
+public class GeneratedEntityGraphTest extends BaseTest {
+
+  @PersistenceContext private EntityManager entityManager;
+
+  @Inject private ProductRepository productRepository;
+
+  @Transactional
+  @Test
+  public void test() {
+    Product product =
+        productRepository
+            .findById(
+                1L,
+                ProductEntityGraph.____()
+                    .brand()
+                    .____
+                    .category()
+                    .____
+                    .maker()
+                    .country()
+                    .____
+                    .____())
+            .orElseThrow(RuntimeException::new);
+
+    assertThat(Hibernate.isInitialized(product.getBrand())).isTrue();
+    assertThat(Hibernate.isInitialized(product.getCategory())).isTrue();
+    assertThat(Hibernate.isInitialized(product.getMaker())).isTrue();
+    assertThat(Hibernate.isInitialized(product.getMaker().getCountry())).isTrue();
+  }
+}
diff --git a/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/GeneratedEntityGraphUnitTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/GeneratedEntityGraphUnitTest.java
new file mode 100644
index 0000000..3261b91
--- /dev/null
+++ b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/GeneratedEntityGraphUnitTest.java
@@ -0,0 +1,51 @@
+package com.cosium.spring.data.jpa.entity.graph.repository;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.cosium.spring.data.jpa.entity.graph.domain.EntityGraph;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.Brand;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.BrandEntityGraph;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.Maker;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.MakerEntityGraph;
+import com.cosium.spring.data.jpa.entity.graph.repository.sample.ProductEntityGraph;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Test;
+
+/** @author Réda Housni Alaoui */
+public class GeneratedEntityGraphUnitTest {
+
+  @Test
+  public void testNoPath() {
+    EntityGraph entityGraph = ProductEntityGraph.____().____();
+    assertThat(entityGraph.getEntityGraphAttributePaths()).isEmpty();
+  }
+
+  @Test
+  public void testMultiplePaths() {
+    EntityGraph entityGraph =
+        ProductEntityGraph.____().brand().____.category().____.maker().country().____.____();
+
+    assertThat(entityGraph.getEntityGraphAttributePaths())
+        .hasSize(3)
+        .contains("brand")
+        .contains("category")
+        .contains("maker.country");
+  }
+
+  @Test
+  public void testPathToMap() {
+    assertThat(new Brand().getProducts()).isInstanceOf(Map.class);
+
+    EntityGraph entityGraph = BrandEntityGraph.____().products().____.____();
+    assertThat(entityGraph.getEntityGraphAttributePaths()).hasSize(1).contains("products");
+  }
+
+  @Test
+  public void testPathToCollection() {
+    assertThat(new Maker().getProducts()).isInstanceOf(Set.class);
+
+    EntityGraph entityGraph = MakerEntityGraph.____().products().____.____();
+    assertThat(entityGraph.getEntityGraphAttributePaths()).hasSize(1).contains("products");
+  }
+}
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/RepositoryTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/RepositoryTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/RepositoryTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/RepositoryTest.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Brand.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Brand.java
similarity index 51%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Brand.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Brand.java
index 9901df4..0173fd4 100644
--- a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Brand.java
+++ b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Brand.java
@@ -1,6 +1,18 @@
 package com.cosium.spring.data.jpa.entity.graph.repository.sample;
 
-import javax.persistence.*;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MapKey;
+import javax.persistence.NamedEntityGraph;
+import javax.persistence.NamedEntityGraphs;
+import javax.persistence.OneToMany;
 
 /**
  * Created on 22/11/16.
@@ -27,6 +39,10 @@ public class Brand {
 
   private String name;
 
+  @OneToMany(fetch = FetchType.LAZY, mappedBy = "brand")
+  @MapKey
+  private final Map<Long, Product> products = new LinkedHashMap<>();
+
   public long getId() {
     return id;
   }
@@ -42,4 +58,8 @@ public String getName() {
   public void setName(String name) {
     this.name = name;
   }
+
+  public Map<Long, Product> getProducts() {
+    return products;
+  }
 }
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/BrandRepository.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/BrandRepository.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/BrandRepository.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/BrandRepository.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Category.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Category.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Category.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Category.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Country.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Country.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Country.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Country.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EmptyEntityGraphSpecification.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EmptyEntityGraphSpecification.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EmptyEntityGraphSpecification.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EmptyEntityGraphSpecification.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EntityGraphSpecification.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EntityGraphSpecification.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EntityGraphSpecification.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/EntityGraphSpecification.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Maker.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Maker.java
similarity index 56%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Maker.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Maker.java
index d0f4c15..902e892 100644
--- a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Maker.java
+++ b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Maker.java
@@ -1,6 +1,20 @@
 package com.cosium.spring.data.jpa.entity.graph.repository.sample;
 
-import javax.persistence.*;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.persistence.Access;
+import javax.persistence.AccessType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.NamedAttributeNode;
+import javax.persistence.NamedEntityGraph;
+import javax.persistence.NamedEntityGraphs;
+import javax.persistence.OneToMany;
 
 /**
  * Created on 24/11/16.
@@ -29,6 +43,9 @@ public class Maker {
   @JoinColumn(nullable = false)
   private Country country;
 
+  @OneToMany(fetch = FetchType.LAZY, mappedBy = "maker")
+  private final Set<Product> products = new LinkedHashSet<>();
+
   public long getId() {
     return id;
   }
@@ -52,4 +69,8 @@ public Country getCountry() {
   public void setCountry(Country country) {
     this.country = country;
   }
+
+  public Set<Product> getProducts() {
+    return products;
+  }
 }
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/MakerRepository.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/MakerRepository.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/MakerRepository.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/MakerRepository.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Product.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Product.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Product.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/Product.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductName.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductName.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductName.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductName.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepository.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepository.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepository.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepository.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryCustom.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryCustom.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryCustom.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryCustom.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryImpl.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryImpl.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryImpl.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/sample/ProductRepositoryImpl.java
diff --git a/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepositoryTest.java b/core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepositoryTest.java
similarity index 100%
rename from src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepositoryTest.java
rename to core/src/test/java/com/cosium/spring/data/jpa/entity/graph/repository/support/EntityGraphQuerydslRepositoryTest.java
diff --git a/src/test/resources/META-INF/orm.xml b/core/src/test/resources/META-INF/orm.xml
similarity index 100%
rename from src/test/resources/META-INF/orm.xml
rename to core/src/test/resources/META-INF/orm.xml
diff --git a/src/test/resources/com/cosium/spring/data/jpa/entity/graph/dataset.xml b/core/src/test/resources/com/cosium/spring/data/jpa/entity/graph/dataset.xml
similarity index 100%
rename from src/test/resources/com/cosium/spring/data/jpa/entity/graph/dataset.xml
rename to core/src/test/resources/com/cosium/spring/data/jpa/entity/graph/dataset.xml
diff --git a/src/test/resources/logback-test.xml b/core/src/test/resources/logback-test.xml
similarity index 100%
rename from src/test/resources/logback-test.xml
rename to core/src/test/resources/logback-test.xml
diff --git a/doc/MAIN.md b/doc/MAIN.md
index fe07238..73be069 100644
--- a/doc/MAIN.md
+++ b/doc/MAIN.md
@@ -86,6 +86,58 @@ and equivalent to writing this in your repository's interface:
 Product findById(Long id);
 ```
 
+## Type safe EntityGraph
+
+Composing 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?
+
+`spring-data-jpa-entity-graph-generator` has you covered. 
+
+This annotation processor makes use of the JPA metamodel informations (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. 
+
+You first need to add a JPA metamodel information generator. `hibernate-jpamodelgen` is great and should be compatible with
+any JPA ORM:
+```xml
+<dependency>
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-jpamodelgen</artifactId>
+    <version>${hibernate.version}</version>
+    <scope>provided</scope>
+</dependency>
+```
+
+Then add the entity graph generator annotation processor dependency:
+
+```xml
+<dependency>
+  <groupId>com.cosium.spring.data</groupId>
+  <artifactId>spring-data-jpa-entity-graph-generator</artifactId>
+  <version>${spring-data-jpa-entity-graph.version}</version>
+  <scope>provided</scope>
+</dependency>
+```
+
+After compiling your project, you should find `XEntityGraph` classes where `X` is the name of your Entity. Thanks to
+them, you will be able to build entity graphs like this:
+
+```java
+// Let's build entity graph "product(brand, category, maker(country))"
+EntityGraph entityGraph = ProductEntityGraph
+                    .____()
+                    .brand()
+                    .____
+                    .category()
+                    .____
+                    .maker()
+                    .country()
+                    .____
+                    .____();
+
+productRepository.findById(1L, entityGraph);
+```
+
 ## Default EntityGraph
 
 For an Entity, you can define its default EntityGraph.  
diff --git a/generator/pom.xml b/generator/pom.xml
new file mode 100644
index 0000000..4ead8ad
--- /dev/null
+++ b/generator/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.cosium.spring.data</groupId>
+    <artifactId>spring-data-jpa-entity-graph-parent</artifactId>
+    <version>2.2.9-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>spring-data-jpa-entity-graph-generator</artifactId>
+
+  <properties>
+    <auto-service.version>1.0-rc6</auto-service.version>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.auto.service</groupId>
+      <artifactId>auto-service</artifactId>
+      <version>${auto-service.version}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
+      <groupId>org.hibernate.javax.persistence</groupId>
+      <artifactId>hibernate-jpa-2.1-api</artifactId>
+      <version>1.0.0.Draft-16</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.squareup</groupId>
+      <artifactId>javapoet</artifactId>
+      <version>1.12.1</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>3.1.0</version>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.cosium.spring.data.jpa.graph.generator</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Composer.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Composer.java
new file mode 100644
index 0000000..b7150f6
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Composer.java
@@ -0,0 +1,9 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import javax.lang.model.util.Elements;
+
+/** @author Réda Housni Alaoui */
+public interface Composer {
+
+  void addPath(Elements elements, MetamodelAttributeTarget target);
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Constants.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Constants.java
new file mode 100644
index 0000000..12f4854
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Constants.java
@@ -0,0 +1,17 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import com.squareup.javapoet.ClassName;
+
+/** @author Réda Housni Alaoui */
+public class Constants {
+
+  private Constants() {}
+
+  public static final ClassName ENTITY_GRAPH_TYPE_CLASS_NAME =
+      ClassName.get("com.cosium.spring.data.jpa.entity.graph.domain", "EntityGraphType");
+
+  public static final ClassName ENTITY_GRAPH_CLASS_NAME =
+      ClassName.get("com.cosium.spring.data.jpa.entity.graph.domain", "EntityGraph");
+
+  public static final String PATH_SEPARATOR = "____";
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/EntityGraph.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/EntityGraph.java
new file mode 100644
index 0000000..e43b4d1
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/EntityGraph.java
@@ -0,0 +1,116 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.Modifier;
+
+/** @author Réda Housni Alaoui */
+public class EntityGraph {
+
+  private final ClassName className;
+  private final TypeSpec typeSpec;
+
+  public EntityGraph(
+      ClassName entityGraphClassName, RootComposer rootComposer, NodeComposer nodeComposer) {
+    this.className = entityGraphClassName;
+
+    FieldSpec typeField =
+        FieldSpec.builder(Constants.ENTITY_GRAPH_TYPE_CLASS_NAME, "type")
+            .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
+            .build();
+
+    FieldSpec attributePathsField =
+        FieldSpec.builder(ParameterizedTypeName.get(List.class, String.class), "attributePaths")
+            .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
+            .build();
+
+    ClassName rootComposerClassName = entityGraphClassName.nestedClass(rootComposer.simpleName());
+
+    MethodSpec constructor =
+        MethodSpec.constructorBuilder()
+            .addModifiers(Modifier.PRIVATE)
+            .addParameter(rootComposerClassName, "rootComposer")
+            .addStatement("this.type = rootComposer.entityGraphType")
+            .addStatement(
+                "this.attributePaths = rootComposer.entityGraphAttributePaths.stream()"
+                    + ".map(pathParts -> String.join(\".\", pathParts)).collect($T.toList())",
+                Collectors.class)
+            .build();
+
+    MethodSpec rootStaticMethod =
+        MethodSpec.methodBuilder(Constants.PATH_SEPARATOR)
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .returns(rootComposerClassName)
+            .addStatement("return new $N()", rootComposer.simpleName())
+            .build();
+
+    MethodSpec rootStaticMethodWithEntityGraphType =
+        MethodSpec.methodBuilder(Constants.PATH_SEPARATOR)
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .addParameter(Constants.ENTITY_GRAPH_TYPE_CLASS_NAME, "entityGraphType")
+            .returns(rootComposerClassName)
+            .addStatement("return new $N(entityGraphType)", rootComposer.simpleName())
+            .build();
+
+    MethodSpec getEntityGraphTypeMethod =
+        MethodSpec.methodBuilder("getEntityGraphType")
+            .addModifiers(Modifier.PUBLIC)
+            .addAnnotation(Override.class)
+            .returns(Constants.ENTITY_GRAPH_TYPE_CLASS_NAME)
+            .addStatement("return type")
+            .build();
+
+    MethodSpec getEntityGraphAttributePathsMethod =
+        MethodSpec.methodBuilder("getEntityGraphAttributePaths")
+            .addModifiers(Modifier.PUBLIC)
+            .addAnnotation(Override.class)
+            .returns(ParameterizedTypeName.get(List.class, String.class))
+            .addStatement("return attributePaths")
+            .build();
+
+    MethodSpec getEntityGraphNameMethod =
+        MethodSpec.methodBuilder("getEntityGraphName")
+            .addModifiers(Modifier.PUBLIC)
+            .addAnnotation(Override.class)
+            .returns(String.class)
+            .addStatement("return null")
+            .build();
+
+    MethodSpec isOptionalMethod =
+        MethodSpec.methodBuilder("isOptional")
+            .addModifiers(Modifier.PUBLIC)
+            .addAnnotation(Override.class)
+            .returns(boolean.class)
+            .addStatement("return false")
+            .build();
+
+    typeSpec =
+        TypeSpec.classBuilder(entityGraphClassName)
+            .addModifiers(Modifier.PUBLIC)
+            .addSuperinterface(Constants.ENTITY_GRAPH_CLASS_NAME)
+            .addField(typeField)
+            .addField(attributePathsField)
+            .addMethod(constructor)
+            .addMethod(rootStaticMethod)
+            .addMethod(rootStaticMethodWithEntityGraphType)
+            .addMethod(getEntityGraphTypeMethod)
+            .addMethod(getEntityGraphAttributePathsMethod)
+            .addMethod(getEntityGraphNameMethod)
+            .addMethod(isOptionalMethod)
+            .addType(rootComposer.toTypeSpec())
+            .addType(nodeComposer.toTypeSpec())
+            .build();
+  }
+
+  public void writeTo(Filer filer) throws IOException {
+    JavaFile.builder(className.packageName(), typeSpec).build().writeTo(filer);
+  }
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/EntityGraphClassName.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/EntityGraphClassName.java
new file mode 100644
index 0000000..ee822dd
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/EntityGraphClassName.java
@@ -0,0 +1,28 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import com.squareup.javapoet.ClassName;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+
+/** @author Réda Housni Alaoui */
+public class EntityGraphClassName {
+
+  private final Elements elements;
+  private final TypeElement entityTypeElement;
+  private final String simpleName;
+
+  public EntityGraphClassName(Elements elements, TypeElement entityTypeElement) {
+    this.elements = elements;
+    this.entityTypeElement = entityTypeElement;
+    this.simpleName = entityTypeElement.getSimpleName() + "EntityGraph";
+  }
+
+  public String simpleName() {
+    return entityTypeElement.getSimpleName() + "EntityGraph";
+  }
+
+  public ClassName toClassName() {
+    return ClassName.get(
+        elements.getPackageOf(entityTypeElement).getQualifiedName().toString(), simpleName);
+  }
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Generator.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Generator.java
new file mode 100644
index 0000000..5c1a6fa
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/Generator.java
@@ -0,0 +1,60 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import com.google.auto.service.AutoService;
+import java.util.Collections;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.persistence.metamodel.StaticMetamodel;
+
+/** @author Réda Housni Alaoui */
+@AutoService(Processor.class)
+public class Generator extends AbstractProcessor {
+
+  private static final Boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = Boolean.FALSE;
+
+  private Types types;
+  private Elements elements;
+  private Filer filer;
+
+  @Override
+  public synchronized void init(ProcessingEnvironment processingEnv) {
+    super.init(processingEnv);
+    this.types = processingEnv.getTypeUtils();
+    this.elements = processingEnv.getElementUtils();
+    this.filer = processingEnv.getFiler();
+  }
+
+  @Override
+  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    if (roundEnv.processingOver() || annotations.isEmpty()) {
+      return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
+    }
+
+    roundEnv
+        .getElementsAnnotatedWith(StaticMetamodel.class)
+        .stream()
+        .map(TypeElement.class::cast)
+        .map(typeElement -> new MetamodelClass(elements, types, typeElement))
+        .forEach(metamodelClass -> metamodelClass.writeEntityGraphTo(filer));
+
+    return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS;
+  }
+
+  @Override
+  public Set<String> getSupportedAnnotationTypes() {
+    return Collections.singleton(StaticMetamodel.class.getCanonicalName());
+  }
+
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latestSupported();
+  }
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelAttribute.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelAttribute.java
new file mode 100644
index 0000000..dac060e
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelAttribute.java
@@ -0,0 +1,65 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import static javax.lang.model.element.ElementKind.FIELD;
+
+import java.util.List;
+import java.util.Optional;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.persistence.Entity;
+import javax.persistence.metamodel.Attribute;
+
+/** @author Réda Housni Alaoui */
+public class MetamodelAttribute {
+
+  private final VariableElement variableElement;
+
+  private MetamodelAttribute(VariableElement variableElement) {
+    this.variableElement = variableElement;
+  }
+
+  public static Optional<MetamodelAttribute> parse(
+      Elements elements, Types types, Element element) {
+    if (!(element instanceof VariableElement)) {
+      return Optional.empty();
+    }
+
+    VariableElement variableElement = (VariableElement) element;
+    if (variableElement.getKind() != FIELD) {
+      return Optional.empty();
+    }
+
+    TypeElement attributeTypeElement = elements.getTypeElement(Attribute.class.getCanonicalName());
+    if (!types.isSubtype(
+        types.erasure(variableElement.asType()), types.erasure(attributeTypeElement.asType()))) {
+      return Optional.empty();
+    }
+
+    return Optional.of(new MetamodelAttribute(variableElement));
+  }
+
+  public Optional<MetamodelAttributeTarget> jpaEntityTarget() {
+    DeclaredType attributeType = (DeclaredType) variableElement.asType();
+    List<? extends TypeMirror> typeArguments = attributeType.getTypeArguments();
+    // This is the lazy way of doing this. We consider that any sub interfaces of
+    // javax.persistence.metamodel.Attribute
+    // will declare the target type as the last type arguments.
+    // e.g. MapAttribute<Brand, Long, Product> where Product is the target
+    // TODO do this cleanly by browsing the class hierarchy
+    DeclaredType targetType = (DeclaredType) typeArguments.get(typeArguments.size() - 1);
+    TypeElement targetTypeElement = (TypeElement) targetType.asElement();
+
+    if (targetTypeElement.getAnnotation(Entity.class) == null) {
+      return Optional.empty();
+    }
+
+    return Optional.of(
+        new MetamodelAttributeTarget(
+            variableElement.getSimpleName().toString(), targetTypeElement));
+  }
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelAttributeTarget.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelAttributeTarget.java
new file mode 100644
index 0000000..d0ce605
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelAttributeTarget.java
@@ -0,0 +1,23 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import javax.lang.model.element.TypeElement;
+
+/** @author Réda Housni Alaoui */
+public class MetamodelAttributeTarget {
+
+  private final String attributeName;
+  private final TypeElement targetType;
+
+  public MetamodelAttributeTarget(String attributeName, TypeElement targetType) {
+    this.attributeName = attributeName;
+    this.targetType = targetType;
+  }
+
+  public String attributeName() {
+    return attributeName;
+  }
+
+  public TypeElement targetType() {
+    return targetType;
+  }
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelClass.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelClass.java
new file mode 100644
index 0000000..8dcc08c
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/MetamodelClass.java
@@ -0,0 +1,69 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import static java.util.Objects.requireNonNull;
+
+import com.squareup.javapoet.ClassName;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import javax.annotation.processing.Filer;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.MirroredTypeException;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.persistence.metamodel.StaticMetamodel;
+
+/** @author Réda Housni Alaoui */
+public class MetamodelClass {
+
+  private final Elements elements;
+  private final Types types;
+  private final TypeElement typeElement;
+
+  public MetamodelClass(Elements elements, Types types, TypeElement typeElement) {
+    this.elements = requireNonNull(elements);
+    this.types = requireNonNull(types);
+    this.typeElement = requireNonNull(typeElement);
+  }
+
+  public void writeEntityGraphTo(Filer filer) {
+    try {
+      doWriteEntityGraphTo(filer);
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private void doWriteEntityGraphTo(Filer filer) throws IOException {
+    StaticMetamodel staticMetamodel = typeElement.getAnnotation(StaticMetamodel.class);
+    TypeElement entityTypeElement;
+    try {
+      staticMetamodel.value();
+      throw new RuntimeException("entityTypeElement.value() didn't throw !");
+    } catch (MirroredTypeException e) {
+      entityTypeElement = (TypeElement) types.asElement(e.getTypeMirror());
+    }
+
+    ClassName entityGraphClassName =
+        new EntityGraphClassName(elements, entityTypeElement).toClassName();
+
+    RootComposer rootComposer = new RootComposer(entityGraphClassName);
+    NodeComposer nodeComposer = new NodeComposer();
+
+    List<Composer> composers = Arrays.asList(rootComposer, nodeComposer);
+
+    elements
+        .getAllMembers(typeElement)
+        .stream()
+        .map(member -> MetamodelAttribute.parse(elements, types, member))
+        .filter(Optional::isPresent)
+        .map(Optional::get)
+        .map(MetamodelAttribute::jpaEntityTarget)
+        .filter(Optional::isPresent)
+        .map(Optional::get)
+        .forEach(attribute -> composers.forEach(composer -> composer.addPath(elements, attribute)));
+
+    new EntityGraph(entityGraphClassName, rootComposer, nodeComposer).writeTo(filer);
+  }
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/NodeComposer.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/NodeComposer.java
new file mode 100644
index 0000000..4de7f79
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/NodeComposer.java
@@ -0,0 +1,74 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeVariableName;
+import java.util.List;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.util.Elements;
+
+/** @author Réda Housni Alaoui */
+public class NodeComposer implements Composer {
+
+  public static final String SIMPLE_NAME = "NodeComposer";
+
+  private final TypeVariableName rootType;
+  private final TypeSpec.Builder typeSpecBuilder;
+
+  public NodeComposer() {
+    rootType = TypeVariableName.get("R");
+
+    FieldSpec rootField =
+        FieldSpec.builder(rootType, Constants.PATH_SEPARATOR)
+            .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
+            .build();
+
+    ParameterizedTypeName listOfString = ParameterizedTypeName.get(List.class, String.class);
+
+    FieldSpec pathField =
+        FieldSpec.builder(listOfString, "path")
+            .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
+            .build();
+
+    MethodSpec constructor =
+        MethodSpec.constructorBuilder()
+            .addModifiers(Modifier.PUBLIC)
+            .addParameter(rootType, "root")
+            .addParameter(listOfString, "path")
+            .addStatement("this.____ = root")
+            .addStatement("this.path = path")
+            .build();
+
+    typeSpecBuilder =
+        TypeSpec.classBuilder(SIMPLE_NAME)
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .addTypeVariable(rootType)
+            .addField(rootField)
+            .addField(pathField)
+            .addMethod(constructor);
+  }
+
+  public TypeSpec toTypeSpec() {
+    return typeSpecBuilder.build();
+  }
+
+  @Override
+  public void addPath(Elements elements, MetamodelAttributeTarget target) {
+    ParameterizedTypeName targetNodeComposer =
+        ParameterizedTypeName.get(
+            new EntityGraphClassName(elements, target.targetType())
+                .toClassName()
+                .nestedClass(SIMPLE_NAME),
+            rootType);
+
+    typeSpecBuilder.addMethod(
+        MethodSpec.methodBuilder(target.attributeName())
+            .addModifiers(Modifier.PUBLIC)
+            .returns(targetNodeComposer)
+            .addStatement("path.add($S)", target.attributeName())
+            .addStatement("return new $T($N, path)", targetNodeComposer, Constants.PATH_SEPARATOR)
+            .build());
+  }
+}
diff --git a/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/RootComposer.java b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/RootComposer.java
new file mode 100644
index 0000000..0e93c8b
--- /dev/null
+++ b/generator/src/main/java/com/cosium/spring/data/jpa/graph/generator/RootComposer.java
@@ -0,0 +1,100 @@
+package com.cosium.spring.data.jpa.graph.generator;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeSpec;
+import java.util.ArrayList;
+import java.util.List;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.util.Elements;
+
+/** @author Réda Housni Alaoui */
+public class RootComposer implements Composer {
+
+  private static final String SIMPLE_NAME = "RootComposer";
+  private final ClassName entityGraphClassName;
+  private final TypeSpec.Builder typeSpecBuilder;
+
+  public RootComposer(ClassName entityGraphClassName) {
+    this.entityGraphClassName = entityGraphClassName;
+
+    FieldSpec entityGraphTypeField =
+        FieldSpec.builder(Constants.ENTITY_GRAPH_TYPE_CLASS_NAME, "entityGraphType")
+            .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
+            .build();
+
+    ParameterizedTypeName listOfString = ParameterizedTypeName.get(List.class, String.class);
+    ParameterizedTypeName listOfListOfString =
+        ParameterizedTypeName.get(ClassName.get(List.class), listOfString);
+
+    FieldSpec entityGraphAttributePathsField =
+        FieldSpec.builder(listOfListOfString, "entityGraphAttributePaths")
+            .addModifiers(Modifier.PRIVATE, Modifier.FINAL)
+            .build();
+
+    MethodSpec constructor =
+        MethodSpec.constructorBuilder()
+            .addModifiers(Modifier.PRIVATE)
+            .addStatement("this($T.$N)", Constants.ENTITY_GRAPH_TYPE_CLASS_NAME, "LOAD")
+            .build();
+
+    MethodSpec constructorWithEntityGraphType =
+        MethodSpec.constructorBuilder()
+            .addModifiers(Modifier.PRIVATE)
+            .addParameter(Constants.ENTITY_GRAPH_TYPE_CLASS_NAME, "entityGraphType")
+            .addStatement("this.entityGraphType = entityGraphType")
+            .addStatement(
+                "entityGraphAttributePaths = new $T()",
+                ParameterizedTypeName.get(ClassName.get(ArrayList.class), listOfString))
+            .build();
+
+    MethodSpec buildMethod =
+        MethodSpec.methodBuilder(Constants.PATH_SEPARATOR)
+            .addModifiers(Modifier.PUBLIC)
+            .returns(entityGraphClassName)
+            .addStatement("return new $T(this)", entityGraphClassName)
+            .build();
+
+    typeSpecBuilder =
+        TypeSpec.classBuilder(SIMPLE_NAME)
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .addField(entityGraphTypeField)
+            .addField(entityGraphAttributePathsField)
+            .addMethod(constructor)
+            .addMethod(constructorWithEntityGraphType)
+            .addMethod(buildMethod);
+  }
+
+  public String simpleName() {
+    return SIMPLE_NAME;
+  }
+
+  public TypeSpec toTypeSpec() {
+    return typeSpecBuilder.build();
+  }
+
+  @Override
+  public void addPath(Elements elements, MetamodelAttributeTarget target) {
+    ParameterizedTypeName targetNodeComposer =
+        ParameterizedTypeName.get(
+            new EntityGraphClassName(elements, target.targetType())
+                .toClassName()
+                .nestedClass(NodeComposer.SIMPLE_NAME),
+            entityGraphClassName.nestedClass(SIMPLE_NAME));
+
+    typeSpecBuilder.addMethod(
+        MethodSpec.methodBuilder(target.attributeName())
+            .addModifiers(Modifier.PUBLIC)
+            .returns(targetNodeComposer)
+            .addStatement(
+                "$T path = new $T()",
+                ParameterizedTypeName.get(List.class, String.class),
+                ParameterizedTypeName.get(ArrayList.class, String.class))
+            .addStatement("path.add($S)", target.attributeName())
+            .addStatement("entityGraphAttributePaths.add(path)")
+            .addStatement("return new $T(this, path)", targetNodeComposer)
+            .build());
+  }
+}
diff --git a/pom.xml b/pom.xml
index ff7a095..82d14b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,128 +2,25 @@
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
 
-  <name>Spring Data JPA EntityGraph</name>
+  <name>Spring Data JPA EntityGraph Parent</name>
   <description>A Spring Data JPA extension allowing full usage of JPA EntityGraph on repositories</description>
   <url>https://github.com/Cosium/spring-data-jpa-entity-graph</url>
 
   <groupId>com.cosium.spring.data</groupId>
-  <artifactId>spring-data-jpa-entity-graph</artifactId>
-  <version>2.2.4-SNAPSHOT</version>
+  <artifactId>spring-data-jpa-entity-graph-parent</artifactId>
+  <version>2.2.9-SNAPSHOT</version>
+  <packaging>pom</packaging>
+
+  <modules>
+    <module>core</module>
+    <module>generator</module>
+  </modules>
 
   <properties>
     <source.level>1.8</source.level>
-    <spring.data.jpa>2.2.6.RELEASE</spring.data.jpa>
-    <eclipselink>2.6.8</eclipselink>
-    <querydsl>4.2.1</querydsl>
-
-    <!--Test-->
-    <dbunit>2.5.3</dbunit>
-    <spring-test-dbunit>1.3.0</spring-test-dbunit>
-    <spring.framework.version>5.2.5.RELEASE</spring.framework.version>
-    <hibernate.version>5.4.13.Final</hibernate.version>
-    <hsqldb.version>2.3.4</hsqldb.version>
-    <assertj>3.8.0</assertj>
-    <logback>1.2.3</logback>
-
-    <!-- Plugins -->
     <maven-git-code-format.version>1.6</maven-git-code-format.version>
   </properties>
 
-  <dependencies>
-    <dependency>
-      <!--Needed by SpringHibernateJpaPersistenceProvider for spring-data-jpa while building with JDK 11-->
-      <groupId>javax.xml.bind</groupId>
-      <artifactId>jaxb-api</artifactId>
-      <version>2.3.0</version>
-      <scope>provided</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.springframework.data</groupId>
-      <artifactId>spring-data-jpa</artifactId>
-      <version>${spring.data.jpa}</version>
-      <scope>provided</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.persistence</groupId>
-      <artifactId>org.eclipse.persistence.jpa</artifactId>
-      <version>${eclipselink}</version>
-      <optional>true</optional>
-    </dependency>
-
-    <dependency>
-      <!--Needed by querydsl for @Generated annotation-->
-      <groupId>javax.annotation</groupId>
-      <artifactId>javax.annotation-api</artifactId>
-      <version>1.3.2</version>
-      <scope>provided</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>com.querydsl</groupId>
-      <artifactId>querydsl-apt</artifactId>
-      <version>${querydsl}</version>
-      <scope>provided</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>com.querydsl</groupId>
-      <artifactId>querydsl-jpa</artifactId>
-      <version>${querydsl}</version>
-      <optional>true</optional>
-    </dependency>
-
-    <!--Test-->
-    <dependency>
-      <groupId>org.hsqldb</groupId>
-      <artifactId>hsqldb</artifactId>
-      <version>${hsqldb.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.hibernate</groupId>
-      <artifactId>hibernate-entitymanager</artifactId>
-      <version>${hibernate.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.12</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>com.github.springtestdbunit</groupId>
-      <artifactId>spring-test-dbunit</artifactId>
-      <version>${spring-test-dbunit}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>spring-test</artifactId>
-      <version>${spring.framework.version}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.dbunit</groupId>
-      <artifactId>dbunit</artifactId>
-      <version>${dbunit}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.assertj</groupId>
-      <artifactId>assertj-core</artifactId>
-      <version>${assertj}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-classic</artifactId>
-      <version>${logback}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
   <build>
     <plugins>
       <plugin>
@@ -206,22 +103,6 @@
           <goals>deploy</goals>
         </configuration>
       </plugin>
-      <plugin>
-        <groupId>com.mysema.maven</groupId>
-        <artifactId>apt-maven-plugin</artifactId>
-        <version>1.1.3</version>
-        <executions>
-          <execution>
-            <goals>
-              <goal>test-process</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>target/generated-test-sources/test-annotations</outputDirectory>
-              <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
       <plugin>
         <groupId>org.jacoco</groupId>
         <artifactId>jacoco-maven-plugin</artifactId>
@@ -241,18 +122,6 @@
           </execution>
         </executions>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-jar-plugin</artifactId>
-        <version>3.1.0</version>
-        <configuration>
-          <archive>
-            <manifestEntries>
-              <Automatic-Module-Name>com.cosium.spring.data.jpa.entity.graph</Automatic-Module-Name>
-            </manifestEntries>
-          </archive>
-        </configuration>
-      </plugin>
     </plugins>
   </build>
 
diff --git a/src/site/resources/settings.xml b/site/settings.xml
similarity index 94%
rename from src/site/resources/settings.xml
rename to site/settings.xml
index 794707b..98a3b35 100644
--- a/src/site/resources/settings.xml
+++ b/site/settings.xml
@@ -10,7 +10,7 @@
                 <repository>
                     <id>central</id>
                     <name>central</name>
-                    <url>http://repo1.maven.org/maven2</url>
+                    <url>https://repo1.maven.org/maven2</url>
                 </repository>
                 <repository>
                     <id>spring-snapshot-local</id>
