From 9446be0b5fedf99f7d7e3baefd5dea3b3f550f0d Mon Sep 17 00:00:00 2001 From: Dmytro Iaroslavskyi Date: Fri, 11 Sep 2015 12:18:36 +0200 Subject: [PATCH] #30 - Added support for Querydsl's QueryDslPredicateExecutor. Original pull request PR #45. --- pom.xml | 15 +++ .../EnversRevisionRepositoryFactoryBean.java | 20 +++- .../QueryDslWithEnversRevisionRepository.java | 77 +++++++++++++++ .../QueryDslRepositoryIntegrationTests.java | 98 +++++++++++++++++++ .../sample/CountryQueryDslRepository.java | 31 ++++++ .../data/envers/sample/QCountry.java | 63 ++++++++++++ 6 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/springframework/data/envers/repository/support/QueryDslWithEnversRevisionRepository.java create mode 100755 src/test/java/org/springframework/data/envers/repository/support/QueryDslRepositoryIntegrationTests.java create mode 100755 src/test/java/org/springframework/data/envers/sample/CountryQueryDslRepository.java create mode 100755 src/test/java/org/springframework/data/envers/sample/QCountry.java 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 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 type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + } + +} \ No newline at end of file