diff --git a/pom.xml b/pom.xml
index 413d9b6..75d9b55 100755
--- a/pom.xml
+++ b/pom.xml
@@ -68,6 +68,21 @@
2.8.2
+
+
+ com.querydsl
+ querydsl-apt
+ ${querydsl}
+ provided
+
+
+
+ com.querydsl
+ querydsl-jpa
+ ${querydsl}
+ true
+
+
com.h2database
diff --git a/src/main/java/org/springframework/data/envers/repository/support/EnversRevisionRepositoryFactoryBean.java b/src/main/java/org/springframework/data/envers/repository/support/EnversRevisionRepositoryFactoryBean.java
index 6acb6ec..de86c92 100755
--- a/src/main/java/org/springframework/data/envers/repository/support/EnversRevisionRepositoryFactoryBean.java
+++ b/src/main/java/org/springframework/data/envers/repository/support/EnversRevisionRepositoryFactoryBean.java
@@ -25,6 +25,8 @@ import org.springframework.core.GenericTypeResolver;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+import org.springframework.data.querydsl.QuerydslUtils;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments;
@@ -116,10 +118,24 @@ public class EnversRevisionRepositoryFactoryBean getRepositoryBaseClass(RepositoryMetadata metadata) {
- return EnversRevisionRepositoryImpl.class;
+ if (isQueryDslExecutor(metadata.getRepositoryInterface())) {
+ return QueryDslWithEnversRevisionRepository.class;
+ } else {
+ return EnversRevisionRepositoryImpl.class;
+ }
}
- /*
+ /**
+ * Returns whether the given repository interface requires a QueryDsl specific implementation to be chosen.
+ *
+ * @param repositoryInterface
+ * @return
+ */
+ private boolean isQueryDslExecutor(Class> repositoryInterface) {
+ return QuerydslUtils.QUERY_DSL_PRESENT && QuerydslPredicateExecutor.class.isAssignableFrom(repositoryInterface);
+ }
+
+ /*
* (non-Javadoc)
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getRepository(java.lang.Class, org.springframework.data.repository.core.support.RepositoryComposition.RepositoryFragments)
*/
diff --git a/src/main/java/org/springframework/data/envers/repository/support/QueryDslWithEnversRevisionRepository.java b/src/main/java/org/springframework/data/envers/repository/support/QueryDslWithEnversRevisionRepository.java
new file mode 100644
index 0000000..1031cc8
--- /dev/null
+++ b/src/main/java/org/springframework/data/envers/repository/support/QueryDslWithEnversRevisionRepository.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.envers.repository.support;
+
+import java.io.Serializable;
+import java.util.Optional;
+
+import javax.persistence.EntityManager;
+
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.history.Revision;
+import org.springframework.data.history.Revisions;
+import org.springframework.data.jpa.repository.support.JpaEntityInformation;
+import org.springframework.data.jpa.repository.support.QuerydslJpaRepository;
+import org.springframework.data.repository.history.support.RevisionEntityInformation;
+
+/**
+ * Repository implementation for both {@link org.springframework.data.repository.history.RevisionRepository} and
+ * {@link org.springframework.data.querydsl.QuerydslPredicateExecutor} interfaces.
+ *
+ * @author Dmytro Iaroslavskyi
+ */
+public class QueryDslWithEnversRevisionRepository>
+ extends QuerydslJpaRepository implements EnversRevisionRepository {
+
+ private final EnversRevisionRepositoryImpl delegateRepository;
+
+ /**
+ * Creates a new {@link QueryDslWithEnversRevisionRepository} using the given {@link JpaEntityInformation},
+ * {@link RevisionEntityInformation} and {@link EntityManager}.
+ *
+ * @param entityInformation must not be {@literal null}.
+ * @param revisionEntityInformation must not be {@literal null}.
+ * @param entityManager must not be {@literal null}.
+ */
+ public QueryDslWithEnversRevisionRepository(JpaEntityInformation entityInformation,
+ RevisionEntityInformation revisionEntityInformation, EntityManager entityManager) {
+ super(entityInformation, entityManager);
+ this.delegateRepository = new EnversRevisionRepositoryImpl(entityInformation, revisionEntityInformation,
+ entityManager);
+ }
+
+ @Override
+ public Optional> findLastChangeRevision(ID id) {
+ return delegateRepository.findLastChangeRevision(id);
+ }
+
+ @Override
+ public Optional> findRevision(ID id, N revisionNumber) {
+ return delegateRepository.findRevision(id, revisionNumber);
+ }
+
+ @Override
+ public Revisions findRevisions(ID id) {
+ return delegateRepository.findRevisions(id);
+ }
+
+ @Override
+ public Page> findRevisions(ID id, Pageable pageable) {
+ return delegateRepository.findRevisions(id, pageable);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/org/springframework/data/envers/repository/support/QueryDslRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/envers/repository/support/QueryDslRepositoryIntegrationTests.java
new file mode 100755
index 0000000..fdc87d4
--- /dev/null
+++ b/src/test/java/org/springframework/data/envers/repository/support/QueryDslRepositoryIntegrationTests.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.envers.repository.support;
+
+import org.hamcrest.Matchers;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.envers.Config;
+import org.springframework.data.envers.sample.Country;
+import org.springframework.data.envers.sample.CountryQueryDslRepository;
+import org.springframework.data.envers.sample.QCountry;
+import org.springframework.data.history.Revision;
+import org.springframework.data.history.Revisions;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.Iterator;
+import java.util.Optional;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Integration tests for repositories with QueryDsl support. They make sure that methods provided by both
+ * {@link EnversRevisionRepository} and {@link org.springframework.data.querydsl.QueryDslPredicateExecutor} are working.
+ *
+ * @author Dmytro Iaroslavskyi
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = Config.class)
+public class QueryDslRepositoryIntegrationTests {
+
+ @Autowired CountryQueryDslRepository countryRepository;
+
+ @Before
+ public void setUp() {
+ countryRepository.deleteAll();
+ }
+
+ @Test
+ public void testWithQueryDsl() {
+
+ Country de = new Country();
+ de.code = "de";
+ de.name = "Deutschland";
+
+ countryRepository.save(de);
+
+ Country found = countryRepository.findOne(QCountry.country.name.eq("Deutschland")).get();
+
+ assertThat(found, is(notNullValue()));
+ assertThat(found.id, is(de.id));
+
+ }
+
+ @Test
+ public void testWithRevisions() {
+
+ Country de = new Country();
+ de.code = "de";
+ de.name = "Deutschland";
+
+ countryRepository.save(de);
+
+ de.name = "Germany";
+
+ countryRepository.save(de);
+
+ Revisions revisions = countryRepository.findRevisions(de.id);
+
+ assertThat(revisions, is(Matchers.>iterableWithSize(2)));
+
+ Iterator> iterator = revisions.iterator();
+ Revision first = iterator.next();
+ Revision second = iterator.next();
+
+ assertThat(countryRepository.findRevision(de.id, first.getRevisionNumber().get()).get().getEntity().name, is("Deutschland"));
+ assertThat(countryRepository.findRevision(de.id, second.getRevisionNumber().get()).get().getEntity().name, is("Germany"));
+
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/envers/sample/CountryQueryDslRepository.java b/src/test/java/org/springframework/data/envers/sample/CountryQueryDslRepository.java
new file mode 100755
index 0000000..5267c16
--- /dev/null
+++ b/src/test/java/org/springframework/data/envers/sample/CountryQueryDslRepository.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.envers.sample;
+
+import org.springframework.data.envers.repository.support.EnversRevisionRepository;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.querydsl.QuerydslPredicateExecutor;
+
+/**
+ * Repository with QueryDsl support for {@link Country} objects.
+ *
+ * @author Dmytro Iaroslavskyi
+ */
+public interface CountryQueryDslRepository
+ extends EnversRevisionRepository, JpaRepository,
+ QuerydslPredicateExecutor {
+
+}
diff --git a/src/test/java/org/springframework/data/envers/sample/QCountry.java b/src/test/java/org/springframework/data/envers/sample/QCountry.java
new file mode 100755
index 0000000..df59661
--- /dev/null
+++ b/src/test/java/org/springframework/data/envers/sample/QCountry.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.envers.sample;
+
+import com.querydsl.core.types.Path;
+import com.querydsl.core.types.PathMetadata;
+import com.querydsl.core.types.dsl.EntityPathBase;
+import com.querydsl.core.types.dsl.PathInits;
+import com.querydsl.core.types.dsl.StringPath;
+
+import static com.querydsl.core.types.PathMetadataFactory.forVariable;
+
+/**
+ * Query class for Country domain.
+ *
+ * @author Dmytro Iaroslavskyi
+ */
+public class QCountry extends EntityPathBase {
+
+ private static final long serialVersionUID = -936338527;
+
+ private static final PathInits INITS = PathInits.DIRECT2;
+
+ public static final QCountry country = new QCountry("country");
+
+ public final StringPath code = createString("code");
+ public final StringPath name = createString("name");
+
+ public QCountry(String variable) {
+ this(Country.class, forVariable(variable), INITS);
+ }
+
+ @SuppressWarnings("all")
+ public QCountry(Path extends Country> path) {
+ this((Class) path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT);
+ }
+
+ public QCountry(PathMetadata metadata) {
+ this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT);
+ }
+
+ public QCountry(PathMetadata metadata, PathInits inits) {
+ this(Country.class, metadata, inits);
+ }
+
+ public QCountry(Class extends Country> type, PathMetadata metadata, PathInits inits) {
+ super(type, metadata, inits);
+ }
+
+}
\ No newline at end of file