diff --git a/pom.xml b/pom.xml
index c652f36..6a76b9d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@
4.2.0.RELEASE
1.8.2.RELEASE
- 4.3.10.Final
+ 4.3.11.Final
5.2.0.Final
2.6.0
2.2.5
diff --git a/src/main/java/org/springframework/data/jpa/datatables/repository/DataTablesUtils.java b/src/main/java/org/springframework/data/jpa/datatables/repository/DataTablesUtils.java
index 211b1ae..bceb4cd 100644
--- a/src/main/java/org/springframework/data/jpa/datatables/repository/DataTablesUtils.java
+++ b/src/main/java/org/springframework/data/jpa/datatables/repository/DataTablesUtils.java
@@ -7,6 +7,7 @@
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Fetch;
import javax.persistence.criteria.From;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
@@ -102,6 +103,29 @@ public Predicate toPredicate(Root root, CriteriaQuery> query,
}
predicate = criteriaBuilder.and(predicate, matchOneColumnPredicate);
}
+ // findAll method does a count query first, and then query for the actual data. Yet in the
+ // count query, adding a JOIN FETCH results in the following error 'query specified join
+ // fetching, but the owner of the fetched association was not present in the select list'
+ // see https://jira.spring.io/browse/DATAJPA-105
+ boolean isCountQuery = query.getResultType() == Long.class;
+ if (isCountQuery) {
+ return predicate;
+ }
+ // add JOIN FETCH when necessary
+ for (ColumnParameter column : input.getColumns()) {
+ if (!column.getSearchable() || !column.getData().contains(ATTRIBUTE_SEPARATOR)) {
+ continue;
+ }
+ String[] values = column.getData().split("\\" + ATTRIBUTE_SEPARATOR);
+ if (root.getModel().getAttribute(values[0])
+ .getPersistentAttributeType() == PersistentAttributeType.EMBEDDED) {
+ continue;
+ }
+ Fetch, ?> fetch = null;
+ for (int i = 0; i < values.length - 1; i++) {
+ fetch = (fetch == null ? root : fetch).fetch(values[i], JoinType.LEFT);
+ }
+ }
return predicate;
}
diff --git a/src/test/java/org/springframework/data/jpa/datatables/Config.java b/src/test/java/org/springframework/data/jpa/datatables/Config.java
index 3daad8f..a1a8fbe 100644
--- a/src/test/java/org/springframework/data/jpa/datatables/Config.java
+++ b/src/test/java/org/springframework/data/jpa/datatables/Config.java
@@ -5,7 +5,9 @@
import javax.sql.DataSource;
+import org.hibernate.SessionFactory;
import org.hibernate.cfg.Environment;
+import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -60,4 +62,10 @@ public AbstractEntityManagerFactoryBean entityManagerFactory() throws SQLExcepti
return bean;
}
+
+ @Bean
+ public SessionFactory sessionFactory() throws SQLException {
+ return ((HibernateEntityManagerFactory) entityManagerFactory().getObject()).getSessionFactory();
+ }
+
}
diff --git a/src/test/java/org/springframework/data/jpa/datatables/repository/LessonRepositoryTest.java b/src/test/java/org/springframework/data/jpa/datatables/repository/LessonRepositoryTest.java
index 0425f7a..1aeee06 100644
--- a/src/test/java/org/springframework/data/jpa/datatables/repository/LessonRepositoryTest.java
+++ b/src/test/java/org/springframework/data/jpa/datatables/repository/LessonRepositoryTest.java
@@ -4,6 +4,8 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import org.hibernate.SessionFactory;
+import org.hibernate.stat.Statistics;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -22,6 +24,9 @@ public class LessonRepositoryTest {
@Autowired
private LessonRepository lessonRepository;
+ @Autowired
+ private SessionFactory sessionFactory;
+
@Test
public void testThroughTwoManyToOneRelationships() {
DataTablesInput input = getBasicInput();
@@ -41,6 +46,22 @@ public void testThroughTwoManyToOneRelationships() {
assertEquals(7, output.getRecordsTotal());
}
+ @Test
+ public void testEagerLoading() {
+ DataTablesInput input = getBasicInput();
+
+ Statistics statistics = sessionFactory.getStatistics();
+ statistics.setStatisticsEnabled(true);
+ DataTablesOutput output = lessonRepository.findAll(input);
+ assertEquals("CourseTypeA", output.getData().get(0).getCourse().getType().getName());
+ statistics.setStatisticsEnabled(false);
+
+ // there should be only three executed queries : count unfiltered, count filtered and actual
+ // data (with FETCH JOIN)
+ assertEquals(3, statistics.getPrepareStatementCount());
+ assertEquals(7 + 3 + 2, statistics.getEntityLoadCount());
+ }
+
/**
*
* @return basic input parameters
diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties
index 924db85..f0ad5b4 100644
--- a/src/test/resources/log4j.properties
+++ b/src/test/resources/log4j.properties
@@ -4,4 +4,5 @@ log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{ABSOLUTE} %5p %40.40c:%4L - %m%n
log4j.appender.console=org.apache.log4j.ConsoleAppender
-log4j.logger.org.springframework=INFO
\ No newline at end of file
+log4j.logger.org.springframework=INFO
+log4j.logger.org.hibernate.SQL=DEBUG