From 493aa7ba0216514f00c437802582fb955d193b58 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 2 Sep 2011 18:14:32 +0200 Subject: [PATCH] DATAJPA-98 - Formatted sources with Spring Data Eclipse formatting settings. --- .gitignore | 4 +- formatting.xml | 291 +++++ .../data/jpa/domain/AbstractAuditable.java | 177 ++- .../data/jpa/domain/AbstractPersistable.java | 150 ++- .../data/jpa/domain/Specification.java | 20 +- .../data/jpa/domain/Specifications.java | 155 ++- .../AuditingBeanFactoryPostProcessor.java | 110 +- .../support/AuditingEntityListener.java | 247 ++-- .../data/jpa/repository/JpaRepository.java | 91 +- .../repository/JpaSpecificationExecutor.java | 85 +- .../data/jpa/repository/Modifying.java | 14 +- .../data/jpa/repository/Query.java | 6 +- .../data/jpa/repository/QueryHints.java | 12 +- .../config/AuditingBeanDefinitionParser.java | 149 +-- .../JpaRepositoryConfigDefinitionParser.java | 180 ++- .../config/JpaRepositoryNameSpaceHandler.java | 21 +- .../SimpleJpaRepositoryConfiguration.java | 190 ++- .../repository/query/AbstractJpaQuery.java | 142 +-- .../query/AbstractStringBasedJpaQuery.java | 19 +- .../query/CriteriaQueryParameterBinder.java | 106 +- .../query/JpaCountQueryCreator.java | 57 +- .../jpa/repository/query/JpaQueryCreator.java | 486 ++++---- .../repository/query/JpaQueryExecution.java | 200 ++- .../query/JpaQueryLookupStrategy.java | 267 ++-- .../jpa/repository/query/JpaQueryMethod.java | 203 ++-- .../data/jpa/repository/query/NamedQuery.java | 173 ++- .../jpa/repository/query/ParameterBinder.java | 200 ++- .../repository/query/PartTreeJpaQuery.java | 265 ++-- .../jpa/repository/query/QueryExtractor.java | 37 +- .../data/jpa/repository/query/QueryUtils.java | 501 ++++---- .../jpa/repository/query/SimpleJpaQuery.java | 164 ++- .../support/JpaEntityInformation.java | 32 +- .../support/JpaEntityInformationSupport.java | 96 +- .../JpaMetamodelEntityInformation.java | 149 ++- .../JpaPersistableEntityInformation.java | 74 +- .../support/JpaRepositoryFactory.java | 197 ++- .../support/JpaRepositoryFactoryBean.java | 94 +- .../support/PersistenceProvider.java | 189 ++- .../support/QueryDslJpaRepository.java | 287 ++--- .../support/QueryDslRepositorySupport.java | 119 +- .../support/SimpleJpaRepository.java | 916 +++++++------- .../jpa/repository/utils/JpaClassUtils.java | 47 +- .../MergingPersistenceUnitManager.java | 72 +- .../data/jpa/domain/sample/Account.java | 3 +- .../data/jpa/domain/sample/AuditableRole.java | 19 +- .../data/jpa/domain/sample/AuditableUser.java | 76 +- .../jpa/domain/sample/AuditorAwareStub.java | 43 +- .../data/jpa/domain/sample/Role.java | 91 +- .../data/jpa/domain/sample/SampleEntity.java | 49 +- .../jpa/domain/sample/SampleEntityPK.java | 91 +- .../data/jpa/domain/sample/SpecialUser.java | 1 - .../data/jpa/domain/sample/User.java | 494 ++++---- .../jpa/domain/sample/UserSpecifications.java | 85 +- ...tingBeanFactoryPostProcessorUnitTests.java | 43 +- .../support/AuditingEntityListenerTests.java | 79 +- .../AuditingEntityListenerUnitTests.java | 161 ++- .../support/AuditingNamespaceUnitTests.java | 40 +- ...lipseLinkNamespaceUserRepositoryTests.java | 7 +- .../EclipseLinkUserRepositoryFinderTests.java | 4 +- .../NamespaceUserRepositoryTests.java | 28 +- .../repository/ORMInfrastructureTests.java | 27 +- .../OpenJpaNamespaceUserRepositoryTests.java | 4 +- .../RoleRepositoryIntegrationTests.java | 39 +- .../SimpleJpaParameterBindingTests.java | 75 +- .../repository/UserRepositoryFinderTests.java | 190 ++- .../jpa/repository/UserRepositoryTests.java | 1074 ++++++++--------- .../config/AbstractRepositoryConfigTests.java | 32 +- .../AuditingBeanDefinitionParserTests.java | 39 +- .../CustomRepositoryFactoryConfigTests.java | 68 +- ...RepositoryConfigDefinitionParserTests.java | 26 +- .../config/QueryLookupStrategyTests.java | 26 +- .../config/RepositoryAutoConfigTests.java | 1 - .../config/RepositoryConfigTests.java | 1 - .../config/TypeFilterConfigTest.java | 31 +- .../custom/CustomGenericJpaRepository.java | 45 +- .../CustomGenericJpaRepositoryFactory.java | 72 +- ...CustomGenericJpaRepositoryFactoryBean.java | 25 +- .../custom/CustomGenericRepository.java | 25 +- .../custom/UserCustomExtendedRepository.java | 28 +- .../query/JpaQueryExecutionUnitTests.java | 120 +- .../query/JpaQueryMethodUnitTests.java | 296 ++--- .../repository/query/NamedQueryUnitTests.java | 48 +- .../query/ParameterBinderUnitTests.java | 232 ++-- .../PartTreeJpaQueryIntegrationTests.java | 43 +- .../repository/query/QueryUtilsUnitTests.java | 179 ++- .../query/SimpleJpaQueryUnitTests.java | 107 +- .../sample/AuditableUserRepository.java | 18 +- .../jpa/repository/sample/RoleRepository.java | 1 - .../jpa/repository/sample/UserRepository.java | 264 ++-- .../sample/UserRepositoryCustom.java | 22 +- .../repository/sample/UserRepositoryImpl.java | 42 +- .../support/EntityManagerFactoryRefTests.java | 35 +- .../EntityManagerFactoryRefUnitTests.java | 49 +- .../JpaEntityInformationSupportUnitTests.java | 60 +- ...PersistableEntityInformationUnitTests.java | 74 +- .../JpaRepositoryFactoryBeanUnitTests.java | 179 ++- .../JpaRepositoryFactoryUnitTests.java | 246 ++-- .../support/JpaRepositoryTests.java | 45 +- ...pleEntityPathResolverUnitTests_Sample.java | 2 +- .../support/QueryDslJpaRepositoryTests.java | 71 +- .../QueryDslRepositorySupportTests.java | 148 ++- .../support/TransactionalRepositoryTests.java | 146 +-- ...ergingPersistenceUnitManagerUnitTests.java | 27 +- 103 files changed, 5843 insertions(+), 6747 deletions(-) create mode 100644 formatting.xml diff --git a/.gitignore b/.gitignore index 8ced21fc2..5cce85cc3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ target/ .settings/ .project .classpath -.springBeans \ No newline at end of file +.springBeans +.sonar4clipse +*.sonar4clipseExternals \ No newline at end of file diff --git a/formatting.xml b/formatting.xml new file mode 100644 index 000000000..c74468778 --- /dev/null +++ b/formatting.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/org/springframework/data/jpa/domain/AbstractAuditable.java b/src/main/java/org/springframework/data/jpa/domain/AbstractAuditable.java index fa018667e..01f5ac299 100644 --- a/src/main/java/org/springframework/data/jpa/domain/AbstractAuditable.java +++ b/src/main/java/org/springframework/data/jpa/domain/AbstractAuditable.java @@ -26,126 +26,115 @@ import javax.persistence.TemporalType; import org.joda.time.DateTime; import org.springframework.data.domain.Auditable; - /** - * Abstract base class for auditable entities. Stores the audition values in - * persistent fields. + * Abstract base class for auditable entities. Stores the audition values in persistent fields. * * @author Oliver Gierke * @param the auditing type. Typically some kind of user. * @param the type of the auditing type's idenifier */ @MappedSuperclass -public abstract class AbstractAuditable extends - AbstractPersistable implements Auditable { +public abstract class AbstractAuditable extends AbstractPersistable implements + Auditable { - private static final long serialVersionUID = 141481953116476081L; + private static final long serialVersionUID = 141481953116476081L; - @OneToOne - private U createdBy; + @OneToOne + private U createdBy; - @Temporal(TemporalType.TIMESTAMP) - private Date createdDate; + @Temporal(TemporalType.TIMESTAMP) + private Date createdDate; - @OneToOne - private U lastModifiedBy; + @OneToOne + private U lastModifiedBy; - @Temporal(TemporalType.TIMESTAMP) - private Date lastModifiedDate; + @Temporal(TemporalType.TIMESTAMP) + private Date lastModifiedDate; + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Auditable#getCreatedBy() + */ + public U getCreatedBy() { - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Auditable#getCreatedBy() - */ - public U getCreatedBy() { + return createdBy; + } - return createdBy; - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.domain.Auditable#setCreatedBy(java.lang.Object) + */ + public void setCreatedBy(final U createdBy) { + this.createdBy = createdBy; + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.domain.Auditable#setCreatedBy(java.lang.Object) - */ - public void setCreatedBy(final U createdBy) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Auditable#getCreatedDate() + */ + public DateTime getCreatedDate() { - this.createdBy = createdBy; - } + return null == createdDate ? null : new DateTime(createdDate); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.domain.Auditable#setCreatedDate(org.joda.time + * .DateTime) + */ + public void setCreatedDate(final DateTime createdDate) { - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Auditable#getCreatedDate() - */ - public DateTime getCreatedDate() { + this.createdDate = null == createdDate ? null : createdDate.toDate(); + } - return null == createdDate ? null : new DateTime(createdDate); - } + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Auditable#getLastModifiedBy() + */ + public U getLastModifiedBy() { + return lastModifiedBy; + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.domain.Auditable#setCreatedDate(org.joda.time - * .DateTime) - */ - public void setCreatedDate(final DateTime createdDate) { + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.domain.Auditable#setLastModifiedBy(java.lang + * .Object) + */ + public void setLastModifiedBy(final U lastModifiedBy) { - this.createdDate = null == createdDate ? null : createdDate.toDate(); - } + this.lastModifiedBy = lastModifiedBy; + } + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Auditable#getLastModifiedDate() + */ + public DateTime getLastModifiedDate() { - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Auditable#getLastModifiedBy() - */ - public U getLastModifiedBy() { + return null == lastModifiedDate ? null : new DateTime(lastModifiedDate); + } - return lastModifiedBy; - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.domain.Auditable#setLastModifiedDate(org.joda + * .time.DateTime) + */ + public void setLastModifiedDate(final DateTime lastModifiedDate) { - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.domain.Auditable#setLastModifiedBy(java.lang - * .Object) - */ - public void setLastModifiedBy(final U lastModifiedBy) { - - this.lastModifiedBy = lastModifiedBy; - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Auditable#getLastModifiedDate() - */ - public DateTime getLastModifiedDate() { - - return null == lastModifiedDate ? null : new DateTime(lastModifiedDate); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.domain.Auditable#setLastModifiedDate(org.joda - * .time.DateTime) - */ - public void setLastModifiedDate(final DateTime lastModifiedDate) { - - this.lastModifiedDate = - null == lastModifiedDate ? null : lastModifiedDate.toDate(); - } + this.lastModifiedDate = null == lastModifiedDate ? null : lastModifiedDate.toDate(); + } } diff --git a/src/main/java/org/springframework/data/jpa/domain/AbstractPersistable.java b/src/main/java/org/springframework/data/jpa/domain/AbstractPersistable.java index 55bdf746e..7ab4bed24 100644 --- a/src/main/java/org/springframework/data/jpa/domain/AbstractPersistable.java +++ b/src/main/java/org/springframework/data/jpa/domain/AbstractPersistable.java @@ -24,110 +24,100 @@ import javax.persistence.MappedSuperclass; import org.springframework.data.domain.Persistable; - /** - * Abstract base class for entities. Allows parameterization of id type, chooses - * auto-generation and implements {@link #equals(Object)} and - * {@link #hashCode()} based on that id. + * Abstract base class for entities. Allows parameterization of id type, chooses auto-generation and implements + * {@link #equals(Object)} and {@link #hashCode()} based on that id. * * @author Oliver Gierke * @param the the of the entity */ @MappedSuperclass -public abstract class AbstractPersistable implements - Persistable { +public abstract class AbstractPersistable implements Persistable { - private static final long serialVersionUID = -5554308939380869754L; + private static final long serialVersionUID = -5554308939380869754L; - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private PK id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private PK id; + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Persistable#getId() + */ + public PK getId() { - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Persistable#getId() - */ - public PK getId() { + return id; + } - return id; - } + /** + * Sets the id of the entity. + * + * @param id the id to set + */ + protected void setId(final PK id) { + this.id = id; + } - /** - * Sets the id of the entity. - * - * @param id the id to set - */ - protected void setId(final PK id) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Persistable#isNew() + */ + public boolean isNew() { - this.id = id; - } + return null == getId(); + } + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.Persistable#isNew() - */ - public boolean isNew() { + return String.format("Entity of type %s with id: %s", this.getClass().getName(), getId()); + } - return null == getId(); - } + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (null == obj) { + return false; + } - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { + if (this == obj) { + return true; + } - return String.format("Entity of type %s with id: %s", this.getClass() - .getName(), getId()); - } + if (!getClass().equals(obj.getClass())) { + return false; + } + AbstractPersistable that = (AbstractPersistable) obj; - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { + return null == this.getId() ? false : this.getId().equals(that.getId()); + } - if (null == obj) { - return false; - } + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { - if (this == obj) { - return true; - } + int hashCode = 17; - if (!getClass().equals(obj.getClass())) { - return false; - } + hashCode += null == getId() ? 0 : getId().hashCode() * 31; - AbstractPersistable that = (AbstractPersistable) obj; - - return null == this.getId() ? false : this.getId().equals(that.getId()); - } - - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - - int hashCode = 17; - - hashCode += null == getId() ? 0 : getId().hashCode() * 31; - - return hashCode; - } + return hashCode; + } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/jpa/domain/Specification.java b/src/main/java/org/springframework/data/jpa/domain/Specification.java index 2863e06bc..13a477145 100644 --- a/src/main/java/org/springframework/data/jpa/domain/Specification.java +++ b/src/main/java/org/springframework/data/jpa/domain/Specification.java @@ -20,7 +20,6 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; - /** * Specification in the sense of Domain Driven Design. * @@ -28,14 +27,13 @@ import javax.persistence.criteria.Root; */ public interface Specification { - /** - * Creates a WHERE clause for a query of the referenced entity in form of a - * {@link Predicate} for the given {@link Root} and {@link CriteriaQuery}. - * - * @param root - * @param query - * @return a {@link Predicate}, must not be {@literal null}. - */ - Predicate toPredicate(Root root, CriteriaQuery query, - CriteriaBuilder cb); + /** + * Creates a WHERE clause for a query of the referenced entity in form of a {@link Predicate} for the given + * {@link Root} and {@link CriteriaQuery}. + * + * @param root + * @param query + * @return a {@link Predicate}, must not be {@literal null}. + */ + Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb); } diff --git a/src/main/java/org/springframework/data/jpa/domain/Specifications.java b/src/main/java/org/springframework/data/jpa/domain/Specifications.java index ba8ef0278..8d1ab2485 100644 --- a/src/main/java/org/springframework/data/jpa/domain/Specifications.java +++ b/src/main/java/org/springframework/data/jpa/domain/Specifications.java @@ -20,7 +20,6 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; - /** * Helper class to easily combine {@link Specification} instances. * @@ -28,106 +27,92 @@ import javax.persistence.criteria.Root; */ public class Specifications implements Specification { - private final Specification spec; + private final Specification spec; + /** + * Creates a new {@link Specifications} wrapper for the given {@link Specification}. + * + * @param spec + */ + private Specifications(Specification spec) { - /** - * Creates a new {@link Specifications} wrapper for the given - * {@link Specification}. - * - * @param spec - */ - private Specifications(Specification spec) { + this.spec = spec; + } - this.spec = spec; - } + /** + * Simple static factory method to add some syntactic sugar around a {@link Specification}. + * + * @param + * @param spec + * @return + */ + public static Specifications where(Specification spec) { + return new Specifications(spec); + } - /** - * Simple static factory method to add some syntactic sugar around a - * {@link Specification}. - * - * @param - * @param spec - * @return - */ - public static Specifications where(Specification spec) { + /** + * ANDs the given {@link Specification} to the current one. + * + * @param other + * @return + */ + public Specifications and(final Specification other) { - return new Specifications(spec); - } + return new Specifications(new Specification() { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - /** - * ANDs the given {@link Specification} to the current one. - * - * @param other - * @return - */ - public Specifications and(final Specification other) { + return builder.and(spec.toPredicate(root, query, builder), other.toPredicate(root, query, builder)); + } + }); + } - return new Specifications(new Specification() { + /** + * ORs the given specification to the current one. + * + * @param other + * @return + */ + public Specifications or(final Specification other) { - public Predicate toPredicate(Root root, CriteriaQuery query, - CriteriaBuilder builder) { + return new Specifications(new Specification() { - return builder.and(spec.toPredicate(root, query, builder), - other.toPredicate(root, query, builder)); - } - }); - } + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { + return builder.or(spec.toPredicate(root, query, builder), other.toPredicate(root, query, builder)); + } + }); + } - /** - * ORs the given specification to the current one. - * - * @param other - * @return - */ - public Specifications or(final Specification other) { + /** + * Negates the given {@link Specification}. + * + * @param + * @param spec + * @return + */ + public static Specifications not(final Specification spec) { - return new Specifications(new Specification() { + return new Specifications(spec) { - public Predicate toPredicate(Root root, CriteriaQuery query, - CriteriaBuilder builder) { + @Override + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return builder.or(spec.toPredicate(root, query, builder), - other.toPredicate(root, query, builder)); - } - }); - } + return builder.not(spec.toPredicate(root, query, builder)); + } + }; + } + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.domain.Specification#toPredicate(javax. + * persistence.criteria.Root, javax.persistence.criteria.CriteriaQuery, + * javax.persistence.criteria.CriteriaBuilder) + */ + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - /** - * Negates the given {@link Specification}. - * - * @param - * @param spec - * @return - */ - public static Specifications not(final Specification spec) { - - return new Specifications(spec) { - - @Override - public Predicate toPredicate(Root root, CriteriaQuery query, - CriteriaBuilder builder) { - - return builder.not(spec.toPredicate(root, query, builder)); - } - }; - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.domain.Specification#toPredicate(javax. - * persistence.criteria.Root, javax.persistence.criteria.CriteriaQuery, - * javax.persistence.criteria.CriteriaBuilder) - */ - public Predicate toPredicate(Root root, CriteriaQuery query, - CriteriaBuilder builder) { - - return spec.toPredicate(root, query, builder); - } + return spec.toPredicate(root, query, builder); + } } diff --git a/src/main/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessor.java b/src/main/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessor.java index 7db2c39cb..6dd470248 100644 --- a/src/main/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessor.java +++ b/src/main/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessor.java @@ -27,82 +27,68 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.data.domain.AuditorAware; import org.springframework.util.StringUtils; - /** * {@link BeanFactoryPostProcessor} to add a {@code depends-on} from a * {@link org.springframework.orm.jpa.LocalEntityManagerFactoryBean} or - * {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} - * towards the aspect bean configured via - * {@code <context:spring-configured>}. This has to be done to ensure the - * aspect is up and running before the - * {@link javax.persistence.EntityManagerFactory} gets created as this already - * instantiates entity listeners and we need to get injection into - * {@link org.springframework.beans.factory.annotation.Configurable} to work in - * them. + * {@link org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean} towards the aspect bean configured via + * {@code <context:spring-configured>}. This has to be done to ensure the aspect is up and running before + * the {@link javax.persistence.EntityManagerFactory} gets created as this already instantiates entity listeners and we + * need to get injection into {@link org.springframework.beans.factory.annotation.Configurable} to work in them. * * @author Oliver Gierke */ -public class AuditingBeanFactoryPostProcessor implements - BeanFactoryPostProcessor { +public class AuditingBeanFactoryPostProcessor implements BeanFactoryPostProcessor { - static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME = - "org.springframework.context.config.internalBeanConfigurerAspect"; + static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME = "org.springframework.context.config.internalBeanConfigurerAspect"; - private static final String JPA_PACKAGE = "org.springframework.orm.jpa."; - private static final List CLASSES_TO_DEPEND = Arrays.asList( - JPA_PACKAGE + "LocalContainerEntityManagerFactoryBean", JPA_PACKAGE - + "LocalEntityManagerFactoryBean"); + private static final String JPA_PACKAGE = "org.springframework.orm.jpa."; + private static final List CLASSES_TO_DEPEND = Arrays.asList(JPA_PACKAGE + + "LocalContainerEntityManagerFactoryBean", JPA_PACKAGE + "LocalEntityManagerFactoryBean"); + /* + * (non-Javadoc) + * + * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor# + * postProcessBeanFactory + * (org.springframework.beans.factory.config.ConfigurableListableBeanFactory + * ) + */ + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { - /* - * (non-Javadoc) - * - * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor# - * postProcessBeanFactory - * (org.springframework.beans.factory.config.ConfigurableListableBeanFactory - * ) - */ - public void postProcessBeanFactory( - ConfigurableListableBeanFactory beanFactory) { + if (!isSpringConfigured(beanFactory)) { + return; + } - if (!isSpringConfigured(beanFactory)) { - return; - } + for (String beanName : beanFactory.getBeanDefinitionNames()) { - for (String beanName : beanFactory.getBeanDefinitionNames()) { + BeanDefinition definition = beanFactory.getBeanDefinition(beanName); - BeanDefinition definition = beanFactory.getBeanDefinition(beanName); + if (CLASSES_TO_DEPEND.contains(definition.getBeanClassName())) { + definition.setDependsOn(StringUtils.addStringToArray(definition.getDependsOn(), + BEAN_CONFIGURER_ASPECT_BEAN_NAME)); + } + } - if (CLASSES_TO_DEPEND.contains(definition.getBeanClassName())) { - definition.setDependsOn(StringUtils.addStringToArray( - definition.getDependsOn(), - BEAN_CONFIGURER_ASPECT_BEAN_NAME)); - } - } + for (String beanName : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, AuditorAware.class, true, + false)) { + BeanDefinition definition = beanFactory.getBeanDefinition(beanName); + definition.setLazyInit(true); + } + } - for (String beanName : BeanFactoryUtils - .beanNamesForTypeIncludingAncestors(beanFactory, - AuditorAware.class, true, false)) { - BeanDefinition definition = beanFactory.getBeanDefinition(beanName); - definition.setLazyInit(true); - } - } + /** + * Returns whether we have a bean factory for which {@code <context:spring-configured>} was activated. + * + * @param factory + * @return + */ + private boolean isSpringConfigured(BeanFactory factory) { - - /** - * Returns whether we have a bean factory for which - * {@code <context:spring-configured>} was activated. - * - * @param factory - * @return - */ - private boolean isSpringConfigured(BeanFactory factory) { - - try { - factory.getBean(BEAN_CONFIGURER_ASPECT_BEAN_NAME); - return true; - } catch (NoSuchBeanDefinitionException e) { - return false; - } - } + try { + factory.getBean(BEAN_CONFIGURER_ASPECT_BEAN_NAME); + return true; + } catch (NoSuchBeanDefinitionException e) { + return false; + } + } } diff --git a/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java b/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java index 6f4047d8b..4e63026e5 100644 --- a/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java +++ b/src/main/java/org/springframework/data/jpa/domain/support/AuditingEntityListener.java @@ -27,11 +27,9 @@ import org.springframework.data.domain.Auditable; import org.springframework.data.domain.AuditorAware; import org.springframework.util.Assert; - /** - * JPA entity listener to capture auditing information on persiting and updating - * entities. To get this one flying be sure you configure it as entity listener - * in your {@code orm.xml} as follows: + * JPA entity listener to capture auditing information on persiting and updating entities. To get this one flying be + * sure you configure it as entity listener in your {@code orm.xml} as follows: * *
  * <persistence-unit-metadata>
@@ -54,167 +52,150 @@ import org.springframework.util.Assert;
 @Configurable
 public class AuditingEntityListener implements InitializingBean {
 
-    private static final Logger LOG = LoggerFactory
-            .getLogger(AuditingEntityListener.class);
+	private static final Logger LOG = LoggerFactory.getLogger(AuditingEntityListener.class);
 
-    private AuditorAware auditorAware;
+	private AuditorAware auditorAware;
 
-    private boolean dateTimeForNow = true;
-    private boolean modifyOnCreation = true;
+	private boolean dateTimeForNow = true;
+	private boolean modifyOnCreation = true;
 
+	/**
+	 * Setter to inject a {@code AuditorAware} component to retrieve the current auditor.
+	 * 
+	 * @param auditorAware the auditorAware to set
+	 */
+	public void setAuditorAware(final AuditorAware auditorAware) {
 
-    /**
-     * Setter to inject a {@code AuditorAware} component to retrieve the current
-     * auditor.
-     * 
-     * @param auditorAware the auditorAware to set
-     */
-    public void setAuditorAware(final AuditorAware auditorAware) {
+		Assert.notNull(auditorAware);
+		this.auditorAware = auditorAware;
+	}
 
-        Assert.notNull(auditorAware);
-        this.auditorAware = auditorAware;
-    }
+	/**
+	 * Setter do determine if {@link Auditable#setCreatedDate(DateTime)} and
+	 * {@link Auditable#setLastModifiedDate(DateTime)} shall be filled with the current Java time. Defaults to
+	 * {@code true}. One might set this to {@code false} to use database features to set entity time.
+	 * 
+	 * @param dateTimeForNow the dateTimeForNow to set
+	 */
+	public void setDateTimeForNow(boolean dateTimeForNow) {
 
+		this.dateTimeForNow = dateTimeForNow;
+	}
 
-    /**
-     * Setter do determine if {@link Auditable#setCreatedDate(DateTime)} and
-     * {@link Auditable#setLastModifiedDate(DateTime)} shall be filled with the
-     * current Java time. Defaults to {@code true}. One might set this to
-     * {@code false} to use database features to set entity time.
-     * 
-     * @param dateTimeForNow the dateTimeForNow to set
-     */
-    public void setDateTimeForNow(boolean dateTimeForNow) {
+	/**
+	 * Set this to false if you want to treat entity creation as modification and thus set the current date as
+	 * modification date, too. Defaults to {@code true}.
+	 * 
+	 * @param modifyOnCreation if modification information shall be set on creation, too
+	 */
+	public void setModifyOnCreation(final boolean modifyOnCreation) {
 
-        this.dateTimeForNow = dateTimeForNow;
-    }
+		this.modifyOnCreation = modifyOnCreation;
+	}
 
+	/**
+	 * Sets modification and creation date and auditor on the target object in case it implements {@link Auditable} on
+	 * persist events.
+	 * 
+	 * @param target
+	 */
+	@PrePersist
+	public void touchForCreate(Object target) {
 
-    /**
-     * Set this to false if you want to treat entity creation as modification
-     * and thus set the current date as modification date, too. Defaults to
-     * {@code true}.
-     * 
-     * @param modifyOnCreation if modification information shall be set on
-     *            creation, too
-     */
-    public void setModifyOnCreation(final boolean modifyOnCreation) {
+		touch(target, true);
+	}
 
-        this.modifyOnCreation = modifyOnCreation;
-    }
+	/**
+	 * Sets modification and creation date and auditor on the target object in case it implements {@link Auditable} on
+	 * update events.
+	 * 
+	 * @param target
+	 */
+	@PreUpdate
+	public void touchForUpdate(Object target) {
 
+		touch(target, false);
+	}
 
-    /**
-     * Sets modification and creation date and auditor on the target object in
-     * case it implements {@link Auditable} on persist events.
-     * 
-     * @param target
-     */
-    @PrePersist
-    public void touchForCreate(Object target) {
+	private void touch(Object target, boolean isNew) {
 
-        touch(target, true);
-    }
+		if (!(target instanceof Auditable)) {
+			return;
+		}
 
+		@SuppressWarnings("unchecked")
+		Auditable auditable = (Auditable) target;
 
-    /**
-     * Sets modification and creation date and auditor on the target object in
-     * case it implements {@link Auditable} on update events.
-     * 
-     * @param target
-     */
-    @PreUpdate
-    public void touchForUpdate(Object target) {
+		T auditor = touchAuditor(auditable, isNew);
+		DateTime now = dateTimeForNow ? touchDate(auditable, isNew) : null;
 
-        touch(target, false);
-    }
+		Object defaultedNow = now == null ? "not set" : now;
+		Object defaultedAuditor = auditor == null ? "unknown" : auditor;
 
+		LOG.debug("Touched {} - Last modification at {} by {}", new Object[] { auditable, defaultedNow, defaultedAuditor });
+	}
 
-    private void touch(Object target, boolean isNew) {
+	/**
+	 * Sets modifying and creating auditioner. Creating auditioner is only set on new auditables.
+	 * 
+	 * @param auditable
+	 * @return
+	 */
+	private T touchAuditor(final Auditable auditable, boolean isNew) {
 
-        if (!(target instanceof Auditable)) {
-            return;
-        }
+		if (null == auditorAware) {
+			return null;
+		}
 
-        @SuppressWarnings("unchecked")
-        Auditable auditable = (Auditable) target;
+		T auditor = auditorAware.getCurrentAuditor();
 
-        T auditor = touchAuditor(auditable, isNew);
-        DateTime now = dateTimeForNow ? touchDate(auditable, isNew) : null;
+		if (isNew) {
 
-        Object defaultedNow = now == null ? "not set" : now;
-        Object defaultedAuditor = auditor == null ? "unknown" : auditor;
+			auditable.setCreatedBy(auditor);
 
-        LOG.debug("Touched {} - Last modification at {} by {}", new Object[] {
-                auditable, defaultedNow, defaultedAuditor });
-    }
+			if (!modifyOnCreation) {
+				return auditor;
+			}
+		}
 
+		auditable.setLastModifiedBy(auditor);
 
-    /**
-     * Sets modifying and creating auditioner. Creating auditioner is only set
-     * on new auditables.
-     * 
-     * @param auditable
-     * @return
-     */
-    private T touchAuditor(final Auditable auditable, boolean isNew) {
+		return auditor;
+	}
 
-        if (null == auditorAware) {
-            return null;
-        }
+	/**
+	 * Touches the auditable regarding modification and creation date. Creation date is only set on new auditables.
+	 * 
+	 * @param auditable
+	 * @return
+	 */
+	private DateTime touchDate(final Auditable auditable, boolean isNew) {
 
-        T auditor = auditorAware.getCurrentAuditor();
+		DateTime now = new DateTime();
 
-        if (isNew) {
+		if (isNew) {
+			auditable.setCreatedDate(now);
 
-            auditable.setCreatedBy(auditor);
+			if (!modifyOnCreation) {
+				return now;
+			}
+		}
 
-            if (!modifyOnCreation) {
-                return auditor;
-            }
-        }
+		auditable.setLastModifiedDate(now);
 
-        auditable.setLastModifiedBy(auditor);
+		return now;
+	}
 
-        return auditor;
-    }
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+	 */
+	public void afterPropertiesSet() {
 
-
-    /**
-     * Touches the auditable regarding modification and creation date. Creation
-     * date is only set on new auditables.
-     * 
-     * @param auditable
-     * @return
-     */
-    private DateTime touchDate(final Auditable auditable, boolean isNew) {
-
-        DateTime now = new DateTime();
-
-        if (isNew) {
-            auditable.setCreatedDate(now);
-
-            if (!modifyOnCreation) {
-                return now;
-            }
-        }
-
-        auditable.setLastModifiedDate(now);
-
-        return now;
-    }
-
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
-     */
-    public void afterPropertiesSet() {
-
-        if (auditorAware == null) {
-            LOG.debug("No AuditorAware set! Auditing will not be applied!");
-        }
-    }
+		if (auditorAware == null) {
+			LOG.debug("No AuditorAware set! Auditing will not be applied!");
+		}
+	}
 }
diff --git a/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java
index e0c769d87..48445d2c6 100644
--- a/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java
+++ b/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java
@@ -23,64 +23,55 @@ import javax.persistence.EntityManager;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.repository.PagingAndSortingRepository;
 
-
 /**
- * JPA specific extension of
- * {@link org.springframework.data.repository.Repository}.
+ * JPA specific extension of {@link org.springframework.data.repository.Repository}.
  * 
  * @author Oliver Gierke
  */
-public interface JpaRepository extends
-        PagingAndSortingRepository {
+public interface JpaRepository extends PagingAndSortingRepository {
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.springframework.data.repository.Repository#findAll()
-     */
-    List findAll();
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.springframework.data.repository.Repository#findAll()
+	 */
+	List findAll();
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.springframework.data.repository.PagingAndSortingRepository#findAll
+	 * (org.springframework.data.domain.Sort)
+	 */
+	List findAll(Sort sort);
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.springframework.data.repository.PagingAndSortingRepository#findAll
-     * (org.springframework.data.domain.Sort)
-     */
-    List findAll(Sort sort);
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.springframework.data.repository.Repository#save(java.lang.Iterable)
+	 */
+	List save(Iterable entities);
 
+	/**
+	 * Flushes all pending changes to the database.
+	 */
+	void flush();
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.springframework.data.repository.Repository#save(java.lang.Iterable)
-     */
-    List save(Iterable entities);
+	/**
+	 * Saves an entity and flushes changes instantly.
+	 * 
+	 * @param entity
+	 * @return the saved entity
+	 */
+	T saveAndFlush(T entity);
 
-
-    /**
-     * Flushes all pending changes to the database.
-     */
-    void flush();
-
-
-    /**
-     * Saves an entity and flushes changes instantly.
-     * 
-     * @param entity
-     * @return the saved entity
-     */
-    T saveAndFlush(T entity);
-
-
-    /**
-     * Deletes the given entities in a batch which means it will create a single
-     * {@link Query}. Assume that we will clear the {@link EntityManager} after
-     * the call.
-     * 
-     * @param entities
-     */
-    void deleteInBatch(Iterable entities);
+	/**
+	 * Deletes the given entities in a batch which means it will create a single {@link Query}. Assume that we will clear
+	 * the {@link EntityManager} after the call.
+	 * 
+	 * @param entities
+	 */
+	void deleteInBatch(Iterable entities);
 }
diff --git a/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java b/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java
index 633c84f4e..fb37dec7f 100644
--- a/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java
+++ b/src/main/java/org/springframework/data/jpa/repository/JpaSpecificationExecutor.java
@@ -22,61 +22,52 @@ import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.domain.Specification;
 
-
 /**
- * Interface to allow execution of {@link Specification}s based on the JPA
- * criteria API.
+ * Interface to allow execution of {@link Specification}s based on the JPA criteria API.
  * 
  * @author Oliver Gierke
  */
 public interface JpaSpecificationExecutor {
 
-    /**
-     * Returns a single entity matching the given {@link Specification}.
-     * 
-     * @param spec
-     * @return
-     */
-    T findOne(Specification spec);
+	/**
+	 * Returns a single entity matching the given {@link Specification}.
+	 * 
+	 * @param spec
+	 * @return
+	 */
+	T findOne(Specification spec);
 
+	/**
+	 * Returns all entities matching the given {@link Specification}.
+	 * 
+	 * @param spec
+	 * @return
+	 */
+	List findAll(Specification spec);
 
-    /**
-     * Returns all entities matching the given {@link Specification}.
-     * 
-     * @param spec
-     * @return
-     */
-    List findAll(Specification spec);
+	/**
+	 * Returns a {@link Page} of entities matching the given {@link Specification}.
+	 * 
+	 * @param spec
+	 * @param pageable
+	 * @return
+	 */
+	Page findAll(Specification spec, Pageable pageable);
 
+	/**
+	 * Returns all entities matching the given {@link Specification} and {@link Sort}.
+	 * 
+	 * @param spec
+	 * @param sort
+	 * @return
+	 */
+	List findAll(Specification spec, Sort sort);
 
-    /**
-     * Returns a {@link Page} of entities matching the given
-     * {@link Specification}.
-     * 
-     * @param spec
-     * @param pageable
-     * @return
-     */
-    Page findAll(Specification spec, Pageable pageable);
-
-
-    /**
-     * Returns all entities matching the given {@link Specification} and
-     * {@link Sort}.
-     * 
-     * @param spec
-     * @param sort
-     * @return
-     */
-    List findAll(Specification spec, Sort sort);
-
-
-    /**
-     * Returns the number of instances that the given {@link Specification} will
-     * return.
-     * 
-     * @param spec the {@link Specification} to count instances for
-     * @return the number of instances
-     */
-    long count(Specification spec);
+	/**
+	 * Returns the number of instances that the given {@link Specification} will return.
+	 * 
+	 * @param spec the {@link Specification} to count instances for
+	 * @return the number of instances
+	 */
+	long count(Specification spec);
 }
diff --git a/src/main/java/org/springframework/data/jpa/repository/Modifying.java b/src/main/java/org/springframework/data/jpa/repository/Modifying.java
index e29531d0d..b2c38b291 100644
--- a/src/main/java/org/springframework/data/jpa/repository/Modifying.java
+++ b/src/main/java/org/springframework/data/jpa/repository/Modifying.java
@@ -21,7 +21,6 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-
 /**
  * Indicates a method should be regarded as modifying query.
  * 
@@ -32,11 +31,10 @@ import java.lang.annotation.Target;
 @Documented
 public @interface Modifying {
 
-    /**
-     * Defines whether we should clear the underlying persistence context after
-     * excuting the modifying query.
-     * 
-     * @return
-     */
-    boolean clearAutomatically() default false;
+	/**
+	 * Defines whether we should clear the underlying persistence context after excuting the modifying query.
+	 * 
+	 * @return
+	 */
+	boolean clearAutomatically() default false;
 }
diff --git a/src/main/java/org/springframework/data/jpa/repository/Query.java b/src/main/java/org/springframework/data/jpa/repository/Query.java
index 4a226ba01..c2fad74dc 100644
--- a/src/main/java/org/springframework/data/jpa/repository/Query.java
+++ b/src/main/java/org/springframework/data/jpa/repository/Query.java
@@ -21,7 +21,6 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-
 /**
  * Annotation to declare finder queries directly on repository methods.
  * 
@@ -32,8 +31,7 @@ import java.lang.annotation.Target;
 @Documented
 public @interface Query {
 
-    String value() default "";
+	String value() default "";
 
-
-    String countQuery() default "";
+	String countQuery() default "";
 }
diff --git a/src/main/java/org/springframework/data/jpa/repository/QueryHints.java b/src/main/java/org/springframework/data/jpa/repository/QueryHints.java
index da814a99d..d375cab4c 100644
--- a/src/main/java/org/springframework/data/jpa/repository/QueryHints.java
+++ b/src/main/java/org/springframework/data/jpa/repository/QueryHints.java
@@ -22,13 +22,11 @@ import java.lang.annotation.Target;
 
 import javax.persistence.QueryHint;
 
-
 /**
- * Wrapper annotation to allow {@link QueryHint} annotations to be bound to
- * methods. It will be evaluated when using {@link Query} on a query method or
- * if you derive the query from the method name. If you rely on named queries
- * either use the XML or annotation based way to declare {@link QueryHint}s in
- * combination with the actual named query declaration.
+ * Wrapper annotation to allow {@link QueryHint} annotations to be bound to methods. It will be evaluated when using
+ * {@link Query} on a query method or if you derive the query from the method name. If you rely on named queries either
+ * use the XML or annotation based way to declare {@link QueryHint}s in combination with the actual named query
+ * declaration.
  * 
  * @author Oliver Gierke
  */
@@ -36,5 +34,5 @@ import javax.persistence.QueryHint;
 @Retention(RetentionPolicy.RUNTIME)
 public @interface QueryHints {
 
-    QueryHint[] value() default {};
+	QueryHint[] value() default {};
 }
diff --git a/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java b/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java
index 304d3fa14..915d33914 100644
--- a/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java
+++ b/src/main/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParser.java
@@ -29,117 +29,94 @@ import org.springframework.beans.factory.xml.ParserContext;
 import org.springframework.util.StringUtils;
 import org.w3c.dom.Element;
 
-
 /**
- * {@link BeanDefinitionParser} for the {@code auditing} element. Sets up an
- * AudE
+ * {@link BeanDefinitionParser} for the {@code auditing} element. Sets up an AudE
  * 
  * @author Oliver Gierke
  */
 public class AuditingBeanDefinitionParser implements BeanDefinitionParser {
 
-    static final String AUDITING_ENTITY_LISTENER_CLASS_NAME =
-            "org.springframework.data.jpa.domain.support.AuditingEntityListener";
-    private static final String AUDITING_BFPP_CLASS_NAME =
-            "org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor";
+	static final String AUDITING_ENTITY_LISTENER_CLASS_NAME = "org.springframework.data.jpa.domain.support.AuditingEntityListener";
+	private static final String AUDITING_BFPP_CLASS_NAME = "org.springframework.data.jpa.domain.support.AuditingBeanFactoryPostProcessor";
 
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.
+	 * w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
+	 */
+	public BeanDefinition parse(Element element, ParserContext parser) {
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.springframework.beans.factory.xml.BeanDefinitionParser#parse(org.
-     * w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext)
-     */
-    public BeanDefinition parse(Element element, ParserContext parser) {
+		new SpringConfiguredBeanDefinitionParser().parse(element, parser);
 
-        new SpringConfiguredBeanDefinitionParser().parse(element, parser);
+		BeanDefinitionBuilder builder = rootBeanDefinition(AUDITING_ENTITY_LISTENER_CLASS_NAME);
+		builder.setScope("prototype");
 
-        BeanDefinitionBuilder builder =
-                rootBeanDefinition(AUDITING_ENTITY_LISTENER_CLASS_NAME);
-        builder.setScope("prototype");
+		String auditorAwareRef = element.getAttribute("auditor-aware-ref");
 
-        String auditorAwareRef = element.getAttribute("auditor-aware-ref");
+		if (StringUtils.hasText(auditorAwareRef)) {
+			builder.addPropertyValue("auditorAware", createLazyInitTargetSourceBeanDefinition(auditorAwareRef));
+		}
 
-        if (StringUtils.hasText(auditorAwareRef)) {
-            builder.addPropertyValue("auditorAware",
-                    createLazyInitTargetSourceBeanDefinition(auditorAwareRef));
-        }
+		builder.addPropertyValue("dateTimeForNow", element.getAttribute("set-dates"));
 
-        builder.addPropertyValue("dateTimeForNow",
-                element.getAttribute("set-dates"));
+		registerInfrastructureBeanWithId(builder.getRawBeanDefinition(), AUDITING_ENTITY_LISTENER_CLASS_NAME, parser,
+				element);
 
-        registerInfrastructureBeanWithId(builder.getRawBeanDefinition(),
-                AUDITING_ENTITY_LISTENER_CLASS_NAME, parser, element);
+		RootBeanDefinition def = new RootBeanDefinition();
+		def.setBeanClassName(AUDITING_BFPP_CLASS_NAME);
+		registerInfrastructureBeanWithId(def, AUDITING_BFPP_CLASS_NAME, parser, element);
 
-        RootBeanDefinition def = new RootBeanDefinition();
-        def.setBeanClassName(AUDITING_BFPP_CLASS_NAME);
-        registerInfrastructureBeanWithId(def, AUDITING_BFPP_CLASS_NAME, parser,
-                element);
+		return null;
+	}
 
-        return null;
-    }
+	private BeanDefinition createLazyInitTargetSourceBeanDefinition(String auditorAwareRef) {
 
+		BeanDefinitionBuilder targetSourceBuilder = rootBeanDefinition(LazyInitTargetSource.class);
+		targetSourceBuilder.addPropertyValue("targetBeanName", auditorAwareRef);
 
-    private BeanDefinition createLazyInitTargetSourceBeanDefinition(
-            String auditorAwareRef) {
+		BeanDefinitionBuilder builder = rootBeanDefinition(ProxyFactoryBean.class);
+		builder.addPropertyValue("targetSource", targetSourceBuilder.getBeanDefinition());
 
-        BeanDefinitionBuilder targetSourceBuilder =
-                rootBeanDefinition(LazyInitTargetSource.class);
-        targetSourceBuilder.addPropertyValue("targetBeanName", auditorAwareRef);
+		return builder.getBeanDefinition();
+	}
 
-        BeanDefinitionBuilder builder =
-                rootBeanDefinition(ProxyFactoryBean.class);
-        builder.addPropertyValue("targetSource",
-                targetSourceBuilder.getBeanDefinition());
+	private void registerInfrastructureBeanWithId(AbstractBeanDefinition def, String id, ParserContext context,
+			Element element) {
 
-        return builder.getBeanDefinition();
-    }
+		def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+		def.setSource(context.extractSource(element));
+		context.registerBeanComponent(new BeanComponentDefinition(def, id));
+	}
 
+	/**
+	 * Copied code of SpringConfiguredBeanDefinitionParser until this class gets public.
+	 * 
+	 * @see http://jira.springframework.org/browse/SPR-7340
+	 * @author Juergen Hoeller
+	 */
+	private static class SpringConfiguredBeanDefinitionParser implements BeanDefinitionParser {
 
-    private void registerInfrastructureBeanWithId(AbstractBeanDefinition def,
-            String id, ParserContext context, Element element) {
+		/**
+		 * The bean name of the internally managed bean configurer aspect.
+		 */
+		private static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME = "org.springframework.context.config.internalBeanConfigurerAspect";
 
-        def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
-        def.setSource(context.extractSource(element));
-        context.registerBeanComponent(new BeanComponentDefinition(def, id));
-    }
+		private static final String BEAN_CONFIGURER_ASPECT_CLASS_NAME = "org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect";
 
-    /**
-     * Copied code of SpringConfiguredBeanDefinitionParser until this class gets
-     * public.
-     * 
-     * @see http://jira.springframework.org/browse/SPR-7340
-     * @author Juergen Hoeller
-     */
-    private static class SpringConfiguredBeanDefinitionParser implements
-            BeanDefinitionParser {
+		public BeanDefinition parse(Element element, ParserContext parserContext) {
 
-        /**
-         * The bean name of the internally managed bean configurer aspect.
-         */
-        private static final String BEAN_CONFIGURER_ASPECT_BEAN_NAME =
-                "org.springframework.context.config.internalBeanConfigurerAspect";
+			if (!parserContext.getRegistry().containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
+				RootBeanDefinition def = new RootBeanDefinition();
+				def.setBeanClassName(BEAN_CONFIGURER_ASPECT_CLASS_NAME);
+				def.setFactoryMethodName("aspectOf");
 
-        private static final String BEAN_CONFIGURER_ASPECT_CLASS_NAME =
-                "org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect";
-
-
-        public BeanDefinition parse(Element element, ParserContext parserContext) {
-
-            if (!parserContext.getRegistry().containsBeanDefinition(
-                    BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
-                RootBeanDefinition def = new RootBeanDefinition();
-                def.setBeanClassName(BEAN_CONFIGURER_ASPECT_CLASS_NAME);
-                def.setFactoryMethodName("aspectOf");
-
-                def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
-                def.setSource(parserContext.extractSource(element));
-                parserContext
-                        .registerBeanComponent(new BeanComponentDefinition(def,
-                                BEAN_CONFIGURER_ASPECT_BEAN_NAME));
-            }
-            return null;
-        }
-    }
+				def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+				def.setSource(parserContext.extractSource(element));
+				parserContext.registerBeanComponent(new BeanComponentDefinition(def, BEAN_CONFIGURER_ASPECT_BEAN_NAME));
+			}
+			return null;
+		}
+	}
 }
diff --git a/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParser.java b/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParser.java
index 79e5ba69c..d7215e717 100644
--- a/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParser.java
+++ b/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParser.java
@@ -26,132 +26,106 @@ import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcesso
 import org.springframework.util.StringUtils;
 import org.w3c.dom.Element;
 
-
 /**
- * Parser to create bean definitions for repositories namespace. Registers bean
- * definitions for repositories as well as
- * {@code PersistenceAnnotationBeanPostProcessor} and
- * {@code PersistenceExceptionTranslationPostProcessor} to transparently inject
- * entity manager factory instance and apply exception translation.
+ * Parser to create bean definitions for repositories namespace. Registers bean definitions for repositories as well as
+ * {@code PersistenceAnnotationBeanPostProcessor} and {@code PersistenceExceptionTranslationPostProcessor} to
+ * transparently inject entity manager factory instance and apply exception translation.
  * 

- * The definition parser allows two ways of configuration. Either it looks up - * the manually defined repository instances or scans the defined domain package - * for candidates for repositories. + * The definition parser allows two ways of configuration. Either it looks up the manually defined repository instances + * or scans the defined domain package for candidates for repositories. * * @author Oliver Gierke * @author Eberhard Wolff * @author Gil Markham */ -class JpaRepositoryConfigDefinitionParser - extends - AbstractRepositoryConfigDefinitionParser { +class JpaRepositoryConfigDefinitionParser extends + AbstractRepositoryConfigDefinitionParser { - private static final Class PAB_POST_PROCESSOR = - PersistenceAnnotationBeanPostProcessor.class; - private static final Class PET_POST_PROCESSOR = - PersistenceExceptionTranslationPostProcessor.class; + private static final Class PAB_POST_PROCESSOR = PersistenceAnnotationBeanPostProcessor.class; + private static final Class PET_POST_PROCESSOR = PersistenceExceptionTranslationPostProcessor.class; + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.config. + * AbstractRepositoryConfigDefinitionParser + * #getGlobalRepositoryConfigInformation(org.w3c.dom.Element) + */ + @Override + protected SimpleJpaRepositoryConfiguration getGlobalRepositoryConfigInformation(Element element) { - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.config. - * AbstractRepositoryConfigDefinitionParser - * #getGlobalRepositoryConfigInformation(org.w3c.dom.Element) - */ - @Override - protected SimpleJpaRepositoryConfiguration getGlobalRepositoryConfigInformation( - Element element) { + return new SimpleJpaRepositoryConfiguration(element); + } - return new SimpleJpaRepositoryConfiguration(element); - } + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.config. + * AbstractRepositoryConfigDefinitionParser + * #postProcessBeanDefinition(org.springframework + * .data.repository.config.SingleRepositoryConfigInformation, + * org.springframework.beans.factory.support.BeanDefinitionBuilder, + * org.springframework.beans.factory.support.BeanDefinitionRegistry, + * java.lang.Object) + */ + @Override + protected void postProcessBeanDefinition(JpaRepositoryConfiguration ctx, BeanDefinitionBuilder builder, + BeanDefinitionRegistry registry, Object beanSource) { + String entityManagerRef = ctx.getEntityManagerFactoryRef(); - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.config. - * AbstractRepositoryConfigDefinitionParser - * #postProcessBeanDefinition(org.springframework - * .data.repository.config.SingleRepositoryConfigInformation, - * org.springframework.beans.factory.support.BeanDefinitionBuilder, - * org.springframework.beans.factory.support.BeanDefinitionRegistry, - * java.lang.Object) - */ - @Override - protected void postProcessBeanDefinition(JpaRepositoryConfiguration ctx, - BeanDefinitionBuilder builder, BeanDefinitionRegistry registry, - Object beanSource) { + if (StringUtils.hasText(entityManagerRef)) { + builder.addPropertyValue("entityManager", getEntityManagerBeanDefinitionFor(entityManagerRef, beanSource)); + } + } - String entityManagerRef = ctx.getEntityManagerFactoryRef(); + /** + * Creates an anonymous factory to extract the actual {@link javax.persistence.EntityManager} from the + * {@link javax.persistence.EntityManagerFactory} bean name reference. + * + * @param entityManagerFactoryBeanName + * @param source + * @return + */ + private BeanDefinition getEntityManagerBeanDefinitionFor(String entityManagerFactoryBeanName, Object source) { - if (StringUtils.hasText(entityManagerRef)) { - builder.addPropertyValue( - "entityManager", - getEntityManagerBeanDefinitionFor(entityManagerRef, - beanSource)); - } - } + BeanDefinitionBuilder builder = BeanDefinitionBuilder + .rootBeanDefinition("org.springframework.orm.jpa.SharedEntityManagerCreator"); + builder.setFactoryMethod("createSharedEntityManager"); + builder.addConstructorArgReference(entityManagerFactoryBeanName); + AbstractBeanDefinition bean = builder.getRawBeanDefinition(); + bean.setSource(source); - /** - * Creates an anonymous factory to extract the actual - * {@link javax.persistence.EntityManager} from the - * {@link javax.persistence.EntityManagerFactory} bean name reference. - * - * @param entityManagerFactoryBeanName - * @param source - * @return - */ - private BeanDefinition getEntityManagerBeanDefinitionFor( - String entityManagerFactoryBeanName, Object source) { + return bean; + } - BeanDefinitionBuilder builder = - BeanDefinitionBuilder - .rootBeanDefinition("org.springframework.orm.jpa.SharedEntityManagerCreator"); - builder.setFactoryMethod("createSharedEntityManager"); - builder.addConstructorArgReference(entityManagerFactoryBeanName); + /** + * Registers an additional {@link org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor} to + * trigger automatic injextion of {@link javax.persistence.EntityManager} . + * + * @param registry + * @param source + */ + @Override + protected void registerBeansForRoot(BeanDefinitionRegistry registry, Object source) { - AbstractBeanDefinition bean = builder.getRawBeanDefinition(); - bean.setSource(source); + super.registerBeansForRoot(registry, source); - return bean; - } + if (!hasBean(PET_POST_PROCESSOR, registry)) { + AbstractBeanDefinition definition = BeanDefinitionBuilder.rootBeanDefinition(PET_POST_PROCESSOR) + .getBeanDefinition(); - /** - * Registers an additional - * {@link org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor} - * to trigger automatic injextion of {@link javax.persistence.EntityManager} - * . - * - * @param registry - * @param source - */ - @Override - protected void registerBeansForRoot(BeanDefinitionRegistry registry, - Object source) { + registerWithSourceAndGeneratedBeanName(registry, definition, source); + } - super.registerBeansForRoot(registry, source); + if (!hasBean(PAB_POST_PROCESSOR, registry)) { - if (!hasBean(PET_POST_PROCESSOR, registry)) { + AbstractBeanDefinition definition = BeanDefinitionBuilder.rootBeanDefinition(PAB_POST_PROCESSOR) + .getBeanDefinition(); - AbstractBeanDefinition definition = - BeanDefinitionBuilder - .rootBeanDefinition(PET_POST_PROCESSOR) - .getBeanDefinition(); - - registerWithSourceAndGeneratedBeanName(registry, definition, source); - } - - if (!hasBean(PAB_POST_PROCESSOR, registry)) { - - AbstractBeanDefinition definition = - BeanDefinitionBuilder - .rootBeanDefinition(PAB_POST_PROCESSOR) - .getBeanDefinition(); - - registerWithSourceAndGeneratedBeanName(registry, definition, source); - } - } + registerWithSourceAndGeneratedBeanName(registry, definition, source); + } + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryNameSpaceHandler.java b/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryNameSpaceHandler.java index d1abedf7b..710c618cd 100644 --- a/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryNameSpaceHandler.java +++ b/src/main/java/org/springframework/data/jpa/repository/config/JpaRepositoryNameSpaceHandler.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.config; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; - /** * Simple namespace handler for {@literal repositories} namespace. * @@ -25,16 +24,14 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport; */ public class JpaRepositoryNameSpaceHandler extends NamespaceHandlerSupport { - /* - * (non-Javadoc) - * - * @see org.springframework.beans.factory.xml.NamespaceHandler#init() - */ - public void init() { + /* + * (non-Javadoc) + * + * @see org.springframework.beans.factory.xml.NamespaceHandler#init() + */ + public void init() { - registerBeanDefinitionParser("repositories", - new JpaRepositoryConfigDefinitionParser()); - registerBeanDefinitionParser("auditing", - new AuditingBeanDefinitionParser()); - } + registerBeanDefinitionParser("repositories", new JpaRepositoryConfigDefinitionParser()); + registerBeanDefinitionParser("auditing", new AuditingBeanDefinitionParser()); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/config/SimpleJpaRepositoryConfiguration.java b/src/main/java/org/springframework/data/jpa/repository/config/SimpleJpaRepositoryConfiguration.java index 09931ca7d..2cca4f3df 100644 --- a/src/main/java/org/springframework/data/jpa/repository/config/SimpleJpaRepositoryConfiguration.java +++ b/src/main/java/org/springframework/data/jpa/repository/config/SimpleJpaRepositoryConfiguration.java @@ -21,134 +21,116 @@ import org.springframework.data.repository.config.RepositoryConfig; import org.springframework.data.repository.config.SingleRepositoryConfigInformation; import org.w3c.dom.Element; - /** * @author Oliver Gierke */ -public class SimpleJpaRepositoryConfiguration - extends - RepositoryConfig { +public class SimpleJpaRepositoryConfiguration extends + RepositoryConfig { - private static final String FACTORY_CLASS = - "org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean"; - private static final String ENTITY_MANAGER_FACTORY_REF = - "entity-manager-factory-ref"; + private static final String FACTORY_CLASS = "org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean"; + private static final String ENTITY_MANAGER_FACTORY_REF = "entity-manager-factory-ref"; + /** + * @param repositoriesElement + */ + public SimpleJpaRepositoryConfiguration(Element repositoriesElement) { - /** - * @param repositoriesElement - */ - public SimpleJpaRepositoryConfiguration(Element repositoriesElement) { + super(repositoriesElement, FACTORY_CLASS); + } - super(repositoriesElement, FACTORY_CLASS); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.config.GlobalRepositoryConfigInformation + * #getAutoconfigRepositoryInformation(java.lang.String) + */ + public JpaRepositoryConfiguration getAutoconfigRepositoryInformation(String interfaceName) { + return new AutomaticJpaRepositoryConfigInformation(interfaceName, this); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.config.GlobalRepositoryConfigInformation - * #getAutoconfigRepositoryInformation(java.lang.String) - */ - public JpaRepositoryConfiguration getAutoconfigRepositoryInformation( - String interfaceName) { + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.config.RepositoryConfigContext + * #getManualRepositoryInformation(org.w3c.dom.Element, + * org.springframework.data + * .jpa.repository.config.CommonRepositoryInformation) + */ + @Override + public JpaRepositoryConfiguration createSingleRepositoryConfigInformationFor(Element element) { - return new AutomaticJpaRepositoryConfigInformation(interfaceName, this); - } + return new ManualJpaRepositoryConfigInformation(element, this); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.config.CommonRepositoryConfigInformation + * #getNamedQueriesLocation() + */ + public String getNamedQueriesLocation() { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.config.RepositoryConfigContext - * #getManualRepositoryInformation(org.w3c.dom.Element, - * org.springframework.data - * .jpa.repository.config.CommonRepositoryInformation) - */ - @Override - public JpaRepositoryConfiguration createSingleRepositoryConfigInformationFor( - Element element) { + return "classpath*:META-INF/jpa-named-queries.properties"; + } - return new ManualJpaRepositoryConfigInformation(element, this); - } + /** + * Returns the name of the entity manager factory bean. + * + * @return + */ + public String getEntityManagerFactoryRef() { + return getSource().getAttribute(ENTITY_MANAGER_FACTORY_REF); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.config.CommonRepositoryConfigInformation - * #getNamedQueriesLocation() - */ - public String getNamedQueriesLocation() { + private static class AutomaticJpaRepositoryConfigInformation extends + AutomaticRepositoryConfigInformation implements JpaRepositoryConfiguration { - return "classpath*:META-INF/jpa-named-queries.properties"; - } + public AutomaticJpaRepositoryConfigInformation(String interfaceName, SimpleJpaRepositoryConfiguration parent) { + super(interfaceName, parent); + } - /** - * Returns the name of the entity manager factory bean. - * - * @return - */ - public String getEntityManagerFactoryRef() { + /** + * Returns the {@link javax.persistence.EntityManagerFactory} reference to be used for all the repository instances + * configured. + * + * @return + */ + public String getEntityManagerFactoryRef() { - return getSource().getAttribute(ENTITY_MANAGER_FACTORY_REF); - } + return getParent().getEntityManagerFactoryRef(); + } + } - private static class AutomaticJpaRepositoryConfigInformation - extends - AutomaticRepositoryConfigInformation - implements JpaRepositoryConfiguration { + private static class ManualJpaRepositoryConfigInformation extends + ManualRepositoryConfigInformation implements JpaRepositoryConfiguration { - public AutomaticJpaRepositoryConfigInformation(String interfaceName, - SimpleJpaRepositoryConfiguration parent) { + public ManualJpaRepositoryConfigInformation(Element element, SimpleJpaRepositoryConfiguration parent) { - super(interfaceName, parent); - } + super(element, parent); + } + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.config. + * SimpleJpaRepositoryConfiguration + * .JpaRepositoryConfiguration#getEntityManagerFactoryRef() + */ + public String getEntityManagerFactoryRef() { - /** - * Returns the {@link javax.persistence.EntityManagerFactory} reference - * to be used for all the repository instances configured. - * - * @return - */ - public String getEntityManagerFactoryRef() { + return getAttribute(ENTITY_MANAGER_FACTORY_REF); + } + } - return getParent().getEntityManagerFactoryRef(); - } - } + static interface JpaRepositoryConfiguration extends + SingleRepositoryConfigInformation { - private static class ManualJpaRepositoryConfigInformation extends - ManualRepositoryConfigInformation - implements JpaRepositoryConfiguration { - - public ManualJpaRepositoryConfigInformation(Element element, - SimpleJpaRepositoryConfiguration parent) { - - super(element, parent); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.config. - * SimpleJpaRepositoryConfiguration - * .JpaRepositoryConfiguration#getEntityManagerFactoryRef() - */ - public String getEntityManagerFactoryRef() { - - return getAttribute(ENTITY_MANAGER_FACTORY_REF); - } - } - - static interface JpaRepositoryConfiguration extends - SingleRepositoryConfigInformation { - - String getEntityManagerFactoryRef(); - } + String getEntityManagerFactoryRef(); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java index c4ac0a219..7bdaf5094 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java @@ -26,7 +26,6 @@ import org.springframework.data.repository.query.QueryMethod; import org.springframework.data.repository.query.RepositoryQuery; import org.springframework.util.Assert; - /** * Abstract base class to implement {@link RepositoryQuery}s. * @@ -34,98 +33,87 @@ import org.springframework.util.Assert; */ public abstract class AbstractJpaQuery implements RepositoryQuery { - private final JpaQueryMethod method; - private final EntityManager em; + private final JpaQueryMethod method; + private final EntityManager em; + /** + * Creates a new {@link AbstractJpaQuery} from the given {@link JpaQueryMethod}. + * + * @param method + * @param em + */ + public AbstractJpaQuery(JpaQueryMethod method, EntityManager em) { - /** - * Creates a new {@link AbstractJpaQuery} from the given - * {@link JpaQueryMethod}. - * - * @param method - * @param em - */ - public AbstractJpaQuery(JpaQueryMethod method, EntityManager em) { + Assert.notNull(method); + Assert.notNull(em); - Assert.notNull(method); - Assert.notNull(em); + this.method = method; + this.em = em; + } - this.method = method; - this.em = em; - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.query.RepositoryQuery#getQueryMethod + * () + */ + public QueryMethod getQueryMethod() { + return method; + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.query.RepositoryQuery#getQueryMethod - * () - */ - public QueryMethod getQueryMethod() { + /** + * @return the em + */ + protected EntityManager getEntityManager() { - return method; - } + return em; + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.query.RepositoryQuery#execute(java + * .lang.Object[]) + */ + public Object execute(Object[] parameters) { - /** - * @return the em - */ - protected EntityManager getEntityManager() { + return doExecute(getExecution(), parameters); + } - return em; - } + /** + * @param execution + * @param values + * @return + */ + private Object doExecute(JpaQueryExecution execution, Object[] values) { + return execution.execute(this, values); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.query.RepositoryQuery#execute(java - * .lang.Object[]) - */ - public Object execute(Object[] parameters) { + protected JpaQueryExecution getExecution() { - return doExecute(getExecution(), parameters); - } + switch (method.getType()) { + case COLLECTION: + return new CollectionExecution(); + case PAGING: + return new PagedExecution(method.getParameters()); + case MODIFYING: + return method.getClearAutomatically() ? new ModifyingExecution(method, em) : new ModifyingExecution(method, null); + default: + return new SingleEntityExecution(); + } + } - /** - * @param execution - * @param values - * @return - */ - private Object doExecute(JpaQueryExecution execution, Object[] values) { + protected ParameterBinder createBinder(Object[] values) { - return execution.execute(this, values); - } + return new ParameterBinder(getQueryMethod().getParameters(), values); + } + protected abstract Query createQuery(Object[] values); - protected JpaQueryExecution getExecution() { - - switch (method.getType()) { - - case COLLECTION: - return new CollectionExecution(); - case PAGING: - return new PagedExecution(method.getParameters()); - case MODIFYING: - return method.getClearAutomatically() ? new ModifyingExecution( - method, em) : new ModifyingExecution(method, null); - default: - return new SingleEntityExecution(); - } - } - - - protected ParameterBinder createBinder(Object[] values) { - - return new ParameterBinder(getQueryMethod().getParameters(), values); - } - - - protected abstract Query createQuery(Object[] values); - - - protected abstract Query createCountQuery(Object[] values); + protected abstract Query createCountQuery(Object[] values); } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java index 208d22993..106ff6e5f 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/AbstractStringBasedJpaQuery.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.query; import javax.persistence.EntityManager; - /** * Base class for {@link String} based JPA queries. * @@ -25,15 +24,15 @@ import javax.persistence.EntityManager; */ public abstract class AbstractStringBasedJpaQuery extends AbstractJpaQuery { - /** - * Creates a new {@link AbstractStringBasedJpaQuery}. - * - * @param method - * @param em - */ - public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em) { + /** + * Creates a new {@link AbstractStringBasedJpaQuery}. + * + * @param method + * @param em + */ + public AbstractStringBasedJpaQuery(JpaQueryMethod method, EntityManager em) { - super(method, em); - } + super(method, em); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/CriteriaQueryParameterBinder.java b/src/main/java/org/springframework/data/jpa/repository/query/CriteriaQueryParameterBinder.java index 4a7300993..576cdcaeb 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/CriteriaQueryParameterBinder.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/CriteriaQueryParameterBinder.java @@ -29,80 +29,68 @@ import org.springframework.data.repository.query.Parameters; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; - /** - * Special {@link ParameterBinder} that uses {@link ParameterExpression}s to - * bind query parameters. + * Special {@link ParameterBinder} that uses {@link ParameterExpression}s to bind query parameters. * * @author Oliver Gierke */ class CriteriaQueryParameterBinder extends ParameterBinder { - private final Iterator> expressions; + private final Iterator> expressions; + /** + * Creates a new {@link CriteriaQueryParameterBinder} for the given {@link Parameters}, values and some + * {@link ParameterExpression}. + * + * @param parameters + */ + CriteriaQueryParameterBinder(Parameters parameters, Object[] values, Iterable> expressions) { - /** - * Creates a new {@link CriteriaQueryParameterBinder} for the given - * {@link Parameters}, values and some {@link ParameterExpression}. - * - * @param parameters - */ - CriteriaQueryParameterBinder(Parameters parameters, Object[] values, - Iterable> expressions) { + super(parameters, values); + Assert.notNull(expressions); + this.expressions = expressions.iterator(); + } - super(parameters, values); - Assert.notNull(expressions); - this.expressions = expressions.iterator(); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.query.ParameterBinder#bind(javax + * .persistence.Query, org.springframework.data.repository.query.Parameter, + * java.lang.Object, int) + */ + @Override + @SuppressWarnings("unchecked") + protected void bind(Query query, Parameter parameter, Object value, int position) { + ParameterExpression expression = (ParameterExpression) expressions.next(); - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.query.ParameterBinder#bind(javax - * .persistence.Query, org.springframework.data.repository.query.Parameter, - * java.lang.Object, int) - */ - @Override - @SuppressWarnings("unchecked") - protected void bind(Query query, Parameter parameter, Object value, - int position) { + Object valueToBind = Collection.class.equals(expression.getJavaType()) ? toCollection(value) : value; - ParameterExpression expression = - (ParameterExpression) expressions.next(); + query.setParameter(expression, valueToBind); + } - Object valueToBind = - Collection.class.equals(expression.getJavaType()) ? toCollection(value) - : value; + /** + * Return sthe given argument as {@link Collection} which means it will return it as is if it's a {@link Collections}, + * turn an array into an {@link ArrayList} or simply wrap any other value into a single element {@link Collections}. + * + * @param value + * @return + */ + private static Collection toCollection(Object value) { - query.setParameter(expression, valueToBind); - } + if (value == null) { + return null; + } + if (value instanceof Collection) { + return (Collection) value; + } - /** - * Return sthe given argument as {@link Collection} which means it will - * return it as is if it's a {@link Collections}, turn an array into an - * {@link ArrayList} or simply wrap any other value into a single element - * {@link Collections}. - * - * @param value - * @return - */ - private static Collection toCollection(Object value) { + if (ObjectUtils.isArray(value)) { + return Arrays.asList(ObjectUtils.toObjectArray(value)); + } - if (value == null) { - return null; - } - - if (value instanceof Collection) { - return (Collection) value; - } - - if (ObjectUtils.isArray(value)) { - return Arrays.asList(ObjectUtils.toObjectArray(value)); - } - - return Collections.singleton(value); - } + return Collections.singleton(value); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java index 06cc099de..0721ce92b 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java @@ -25,7 +25,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.parser.PartTree; - /** * Special {@link JpaQueryCreator} that creates a count projecting query. * @@ -33,36 +32,34 @@ import org.springframework.data.repository.query.parser.PartTree; */ public class JpaCountQueryCreator extends JpaQueryCreator { - /** - * Creates a new {@link JpaCountQueryCreator}. - * - * @param tree - * @param domainClass - * @param parameters - * @param em - */ - public JpaCountQueryCreator(PartTree tree, Class domainClass, - Parameters parameters, EntityManager em) { + /** + * Creates a new {@link JpaCountQueryCreator}. + * + * @param tree + * @param domainClass + * @param parameters + * @param em + */ + public JpaCountQueryCreator(PartTree tree, Class domainClass, Parameters parameters, EntityManager em) { - super(tree, domainClass, parameters, em); - } + super(tree, domainClass, parameters, em); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.query.JpaQueryCreator#complete + * (javax.persistence.criteria.Predicate, + * org.springframework.data.domain.Sort, + * javax.persistence.criteria.CriteriaQuery, + * javax.persistence.criteria.CriteriaBuilder, + * javax.persistence.criteria.Root) + */ + @Override + protected CriteriaQuery complete(Predicate predicate, Sort sort, CriteriaQuery query, + CriteriaBuilder builder, Root root) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.query.JpaQueryCreator#complete - * (javax.persistence.criteria.Predicate, - * org.springframework.data.domain.Sort, - * javax.persistence.criteria.CriteriaQuery, - * javax.persistence.criteria.CriteriaBuilder, - * javax.persistence.criteria.Root) - */ - @Override - protected CriteriaQuery complete(Predicate predicate, Sort sort, - CriteriaQuery query, CriteriaBuilder builder, Root root) { - - return query.select(builder.count(root)).where(predicate); - } + return query.select(builder.count(root)).where(predicate); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java index 04395e7ac..4522acb1f 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java @@ -41,315 +41,269 @@ import org.springframework.data.repository.query.parser.PartTree; import org.springframework.data.repository.query.parser.Property; import org.springframework.util.Assert; - /** * Query creator to create a {@link CriteriaQuery} from a {@link PartTree}. * * @author Oliver Gierke */ -public class JpaQueryCreator extends - AbstractQueryCreator, Predicate> { +public class JpaQueryCreator extends AbstractQueryCreator, Predicate> { - private final CriteriaBuilder builder; - private final Root root; - private final CriteriaQuery query; - private final ParameterExpressionProvider provider; + private final CriteriaBuilder builder; + private final Root root; + private final CriteriaQuery query; + private final ParameterExpressionProvider provider; + /** + * Create a new {@link JpaQueryCreator}. + * + * @param tree + * @param domainClass + * @param accessor + * @param em + */ + public JpaQueryCreator(PartTree tree, Class domainClass, Parameters parameters, EntityManager em) { - /** - * Create a new {@link JpaQueryCreator}. - * - * @param tree - * @param domainClass - * @param accessor - * @param em - */ - public JpaQueryCreator(PartTree tree, Class domainClass, - Parameters parameters, EntityManager em) { + super(tree); - super(tree); + this.builder = em.getCriteriaBuilder(); + this.query = builder.createQuery().distinct(tree.isDistinct()); + this.root = query.from(domainClass); + this.provider = new ParameterExpressionProvider(builder, parameters.getBindableParameters()); + } - this.builder = em.getCriteriaBuilder(); - this.query = builder.createQuery().distinct(tree.isDistinct()); - this.root = query.from(domainClass); - this.provider = - new ParameterExpressionProvider(builder, - parameters.getBindableParameters()); - } + /** + * Returns all {@link ParameterExpression} created when creating the query. + * + * @return the parameterExpressions + */ + public List> getParameterExpressions() { + return provider.getExpressions(); + } - /** - * Returns all {@link ParameterExpression} created when creating the query. - * - * @return the parameterExpressions - */ - public List> getParameterExpressions() { + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.query.parser.AbstractQueryCreator + * #create(org.springframework.data.repository.query.parser.Part, + * java.util.Iterator) + */ + @Override + protected Predicate create(Part part, Iterator iterator) { - return provider.getExpressions(); - } + return toPredicate(part, root); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.query.parser.AbstractQueryCreator + * #and(org.springframework.data.repository.query.parser.Part, + * java.lang.Object, java.util.Iterator) + */ + @Override + protected Predicate and(Part part, Predicate base, Iterator iterator) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.query.parser.AbstractQueryCreator - * #create(org.springframework.data.repository.query.parser.Part, - * java.util.Iterator) - */ - @Override - protected Predicate create(Part part, Iterator iterator) { + return builder.and(base, toPredicate(part, root)); + } - return toPredicate(part, root); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.query.parser.AbstractQueryCreator + * #or(java.lang.Object, java.lang.Object) + */ + @Override + protected Predicate or(Predicate base, Predicate predicate) { + return builder.or(base, predicate); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.query.parser.AbstractQueryCreator - * #and(org.springframework.data.repository.query.parser.Part, - * java.lang.Object, java.util.Iterator) - */ - @Override - protected Predicate and(Part part, Predicate base, Iterator iterator) { + /** + * Finalizes the given {@link Predicate} and applies the given sort. Delegates to + * {@link #complete(Predicate, Sort, CriteriaQuery, CriteriaBuilder)} and hands it the current {@link CriteriaQuery} + * and {@link CriteriaBuilder}. + */ + @Override + protected final CriteriaQuery complete(Predicate predicate, Sort sort) { - return builder.and(base, toPredicate(part, root)); - } + return complete(predicate, sort, query, builder, root); + } + /** + * Template method to finalize the given {@link Predicate} using the given {@link CriteriaQuery} and + * {@link CriteriaBuilder}. + * + * @param predicate + * @param sort + * @param query + * @param builder + * @return + */ + protected CriteriaQuery complete(Predicate predicate, Sort sort, CriteriaQuery query, + CriteriaBuilder builder, Root root) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.query.parser.AbstractQueryCreator - * #or(java.lang.Object, java.lang.Object) - */ - @Override - protected Predicate or(Predicate base, Predicate predicate) { + return this.query.select(root).where(predicate).orderBy(QueryUtils.toOrders(sort, root, builder)); + } - return builder.or(base, predicate); - } + /** + * Creates a {@link Predicate} from the given {@link Part}. + * + * @param part + * @param root + * @param iterator + * @return + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + private Predicate toPredicate(Part part, Root root) { + Property property = part.getProperty(); + Expression path = toExpressionRecursively(root, property); - /** - * Finalizes the given {@link Predicate} and applies the given sort. - * Delegates to - * {@link #complete(Predicate, Sort, CriteriaQuery, CriteriaBuilder)} and - * hands it the current {@link CriteriaQuery} and {@link CriteriaBuilder}. - */ - @Override - protected final CriteriaQuery complete(Predicate predicate, - Sort sort) { + switch (part.getType()) { - return complete(predicate, sort, query, builder, root); - } + case BETWEEN: + ParameterExpression first = provider.next(); + ParameterExpression second = provider.next(); + return builder.between(root. get(part.getProperty().toDotPath()), first, second); + case GREATER_THAN: + return builder.greaterThan(getComparablePath(root, part), provider.next(Comparable.class)); + case LESS_THAN: + return builder.lessThan(getComparablePath(root, part), provider.next(Comparable.class)); + case IS_NULL: + return path.isNull(); + case IS_NOT_NULL: + return path.isNotNull(); + case NOT_IN: + return path.in(provider.next(Collection.class)).not(); + case IN: + return path.in(provider.next(Collection.class)); + case LIKE: + return builder.like(root. get(part.getProperty().toDotPath()), provider.next(String.class)); + case NOT_LIKE: + return builder.like(root. get(part.getProperty().toDotPath()), provider.next(String.class)).not(); + case SIMPLE_PROPERTY: + return builder.equal(path, provider.next()); + case NEGATING_SIMPLE_PROPERTY: + return builder.notEqual(path, provider.next()); + default: + throw new IllegalArgumentException("Unsupported keyword + " + part.getType()); + } + } + private Expression toExpressionRecursively(Path path, Property property) { - /** - * Template method to finalize the given {@link Predicate} using the given - * {@link CriteriaQuery} and {@link CriteriaBuilder}. - * - * @param predicate - * @param sort - * @param query - * @param builder - * @return - */ - protected CriteriaQuery complete(Predicate predicate, Sort sort, - CriteriaQuery query, CriteriaBuilder builder, Root root) { + Path result = path.get(property.getName()); + return property.hasNext() ? toExpressionRecursively(result, property.next()) : result; + } - return this.query.select(root).where(predicate) - .orderBy(QueryUtils.toOrders(sort, root, builder)); - } + @SuppressWarnings("unchecked") + private Expression toExpressionRecursively(From from, Property property) { + if (property.isCollection()) { + Join join = from.join(property.getName()); + return (Expression) (property.hasNext() ? toExpressionRecursively((From) join, property.next()) : join); + } else { + Path path = from.get(property.getName()); + return (Expression) (property.hasNext() ? toExpressionRecursively(path, property.next()) : path); + } + } - /** - * Creates a {@link Predicate} from the given {@link Part}. - * - * @param part - * @param root - * @param iterator - * @return - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - private Predicate toPredicate(Part part, Root root) { + /** + * Returns a path to a {@link Comparable}. + * + * @param root + * @param part + * @return + */ + @SuppressWarnings({ "rawtypes" }) + private Expression getComparablePath(Root root, Part part) { - Property property = part.getProperty(); - Expression path = toExpressionRecursively(root, property); + return toExpressionRecursively(root, part.getProperty()); + } - switch (part.getType()) { + /** + * Helper class to allow easy creation of {@link ParameterExpression}s. + * + * @author Oliver Gierke + */ + private static class ParameterExpressionProvider { - case BETWEEN: - ParameterExpression first = provider.next(); - ParameterExpression second = provider.next(); - return builder.between( - root. get(part.getProperty().toDotPath()), - first, second); - case GREATER_THAN: - return builder.greaterThan(getComparablePath(root, part), - provider.next(Comparable.class)); - case LESS_THAN: - return builder.lessThan(getComparablePath(root, part), - provider.next(Comparable.class)); - case IS_NULL: - return path.isNull(); - case IS_NOT_NULL: - return path.isNotNull(); - case NOT_IN: - return path.in(provider.next(Collection.class)).not(); - case IN: - return path.in(provider.next(Collection.class)); - case LIKE: - return builder.like( - root. get(part.getProperty().toDotPath()), - provider.next(String.class)); - case NOT_LIKE: - return builder.like( - root. get(part.getProperty().toDotPath()), - provider.next(String.class)).not(); - case SIMPLE_PROPERTY: - return builder.equal(path, provider.next()); - case NEGATING_SIMPLE_PROPERTY: - return builder.notEqual(path, provider.next()); - default: - throw new IllegalArgumentException("Unsupported keyword + " - + part.getType()); - } - } + private final CriteriaBuilder builder; + private final Iterator parameters; + private final List> expressions; + /** + * Creates a new {@link ParameterExpressionProvider} from the given {@link CriteriaBuilder} and {@link Parameters}. + * + * @param builder + * @param parameters + */ + public ParameterExpressionProvider(CriteriaBuilder builder, Parameters parameters) { - private Expression toExpressionRecursively(Path path, - Property property) { + Assert.notNull(builder); + Assert.notNull(parameters); - Path result = path.get(property.getName()); - return property.hasNext() ? toExpressionRecursively(result, - property.next()) : result; - } + this.builder = builder; + this.parameters = parameters.iterator(); + this.expressions = new ArrayList>(); + } + /** + * Returns all {@link ParameterExpression}s built. + * + * @return the expressions + */ + public List> getExpressions() { - @SuppressWarnings("unchecked") - private Expression toExpressionRecursively(From from, - Property property) { + return Collections.unmodifiableList(expressions); + } - if (property.isCollection()) { - Join join = from.join(property.getName()); - return (Expression) (property.hasNext() ? toExpressionRecursively( - (From) join, property.next()) : join); - } else { - Path path = from.get(property.getName()); - return (Expression) (property.hasNext() ? toExpressionRecursively( - path, property.next()) : path); - } - } + /** + * Builds a new {@link ParameterExpression} for the next {@link Parameter}. + * + * @param + * @return + */ + @SuppressWarnings("unchecked") + public ParameterExpression next() { + Parameter parameter = parameters.next(); + return (ParameterExpression) next(parameter.getType(), parameter.getName()); + } - /** - * Returns a path to a {@link Comparable}. - * - * @param root - * @param part - * @return - */ - @SuppressWarnings({ "rawtypes" }) - private Expression getComparablePath(Root root, - Part part) { + /** + * Builds a new {@link ParameterExpression} of the given type. Forwards the underlying {@link Parameters} as well. + * + * @param + * @param type must not be {@literal null}. + * @return + */ + public ParameterExpression next(Class type) { - return toExpressionRecursively(root, part.getProperty()); - } + parameters.next(); + return next(type, null); + } - /** - * Helper class to allow easy creation of {@link ParameterExpression}s. - * - * @author Oliver Gierke - */ - private static class ParameterExpressionProvider { + /** + * Builds a new {@link ParameterExpression} for the given type and name. + * + * @param + * @param type must not be {@literal null}. + * @param name + * @return + */ + @SuppressWarnings("unchecked") + private ParameterExpression next(Class type, String name) { - private final CriteriaBuilder builder; - private final Iterator parameters; - private final List> expressions; + Assert.notNull(type); - - /** - * Creates a new {@link ParameterExpressionProvider} from the given - * {@link CriteriaBuilder} and {@link Parameters}. - * - * @param builder - * @param parameters - */ - public ParameterExpressionProvider(CriteriaBuilder builder, - Parameters parameters) { - - Assert.notNull(builder); - Assert.notNull(parameters); - - this.builder = builder; - this.parameters = parameters.iterator(); - this.expressions = new ArrayList>(); - } - - - /** - * Returns all {@link ParameterExpression}s built. - * - * @return the expressions - */ - public List> getExpressions() { - - return Collections.unmodifiableList(expressions); - } - - - /** - * Builds a new {@link ParameterExpression} for the next - * {@link Parameter}. - * - * @param - * @return - */ - @SuppressWarnings("unchecked") - public ParameterExpression next() { - - Parameter parameter = parameters.next(); - return (ParameterExpression) next(parameter.getType(), - parameter.getName()); - } - - - /** - * Builds a new {@link ParameterExpression} of the given type. Forwards - * the underlying {@link Parameters} as well. - * - * @param - * @param type must not be {@literal null}. - * @return - */ - public ParameterExpression next(Class type) { - - parameters.next(); - return next(type, null); - } - - - /** - * Builds a new {@link ParameterExpression} for the given type and name. - * - * @param - * @param type must not be {@literal null}. - * @param name - * @return - */ - @SuppressWarnings("unchecked") - private ParameterExpression next(Class type, String name) { - - Assert.notNull(type); - - ParameterExpression expression = - name == null ? builder.parameter(type) : builder.parameter( - type, name); - expressions.add(expression); - return (ParameterExpression) expression; - } - } + ParameterExpression expression = name == null ? builder.parameter(type) : builder.parameter(type, name); + expressions.add(expression); + return (ParameterExpression) expression; + } + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java index 981348926..33d362483 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java @@ -27,150 +27,130 @@ import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.QueryMethod; import org.springframework.util.Assert; - /** - * Set of classes to contain query execution strategies. Depending (mostly) on - * the return type of a {@link QueryMethod} a - * {@link AbstractStringBasedJpaQuery} can be executed in various flavours. + * Set of classes to contain query execution strategies. Depending (mostly) on the return type of a {@link QueryMethod} + * a {@link AbstractStringBasedJpaQuery} can be executed in various flavours. * * @author Oliver Gierke */ public abstract class JpaQueryExecution { - /** - * Executes the given {@link AbstractStringBasedJpaQuery} with the given - * {@link ParameterBinder}. - * - * @param query - * @param binder - * @return - */ + /** + * Executes the given {@link AbstractStringBasedJpaQuery} with the given {@link ParameterBinder}. + * + * @param query + * @param binder + * @return + */ - public Object execute(AbstractJpaQuery query, Object[] values) { + public Object execute(AbstractJpaQuery query, Object[] values) { - Assert.notNull(query); - Assert.notNull(values); + Assert.notNull(query); + Assert.notNull(values); - try { - return doExecute(query, values); - } catch (NoResultException e) { - return null; - } - } + try { + return doExecute(query, values); + } catch (NoResultException e) { + return null; + } + } + /** + * Method to implement {@link AbstractStringBasedJpaQuery} executions by single enum values. + * + * @param query + * @param binder + * @return + */ + protected abstract Object doExecute(AbstractJpaQuery query, Object[] values); - /** - * Method to implement {@link AbstractStringBasedJpaQuery} executions by - * single enum values. - * - * @param query - * @param binder - * @return - */ - protected abstract Object doExecute(AbstractJpaQuery query, Object[] values); + /** + * Executes the {@link AbstractStringBasedJpaQuery} to return a simple collection of entities. + */ + static class CollectionExecution extends JpaQueryExecution { - /** - * Executes the {@link AbstractStringBasedJpaQuery} to return a simple - * collection of entities. - */ - static class CollectionExecution extends JpaQueryExecution { + @Override + protected Object doExecute(AbstractJpaQuery query, Object[] values) { - @Override - protected Object doExecute(AbstractJpaQuery query, Object[] values) { + return query.createQuery(values).getResultList(); + } + } - return query.createQuery(values).getResultList(); - } - } + /** + * Executes the {@link AbstractStringBasedJpaQuery} to return a {@link Page} of entities. + */ + static class PagedExecution extends JpaQueryExecution { - /** - * Executes the {@link AbstractStringBasedJpaQuery} to return a {@link Page} - * of entities. - */ - static class PagedExecution extends JpaQueryExecution { + private final Parameters parameters; - private final Parameters parameters; + public PagedExecution(Parameters parameters) { + this.parameters = parameters; + } - public PagedExecution(Parameters parameters) { + @Override + @SuppressWarnings("unchecked") + protected Object doExecute(AbstractJpaQuery repositoryQuery, Object[] values) { - this.parameters = parameters; - } + // Execute query to compute total + Query projection = repositoryQuery.createCountQuery(values); + Long total = (Long) projection.getSingleResult(); + Query query = repositoryQuery.createQuery(values); - @Override - @SuppressWarnings("unchecked") - protected Object doExecute(AbstractJpaQuery repositoryQuery, - Object[] values) { + ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); - // Execute query to compute total - Query projection = repositoryQuery.createCountQuery(values); - Long total = (Long) projection.getSingleResult(); + return new PageImpl(query.getResultList(), accessor.getPageable(), total); + } + } - Query query = repositoryQuery.createQuery(values); + /** + * Executes a {@link AbstractStringBasedJpaQuery} to return a single entity. + */ + static class SingleEntityExecution extends JpaQueryExecution { - ParameterAccessor accessor = - new ParametersParameterAccessor(parameters, values); + @Override + protected Object doExecute(AbstractJpaQuery query, Object[] values) { - return new PageImpl(query.getResultList(), - accessor.getPageable(), total); - } - } + return query.createQuery(values).getSingleResult(); + } + } - /** - * Executes a {@link AbstractStringBasedJpaQuery} to return a single entity. - */ - static class SingleEntityExecution extends JpaQueryExecution { + /** + * Executes a modifying query such as an update, insert or delete. + */ + static class ModifyingExecution extends JpaQueryExecution { - @Override - protected Object doExecute(AbstractJpaQuery query, Object[] values) { + private final EntityManager em; - return query.createQuery(values).getSingleResult(); - } - } + /** + * Creates an execution that automatically clears the given {@link EntityManager} after execution if the given + * {@link EntityManager} is not {@literal null}. + * + * @param em + */ + public ModifyingExecution(JpaQueryMethod method, EntityManager em) { - /** - * Executes a modifying query such as an update, insert or delete. - */ - static class ModifyingExecution extends JpaQueryExecution { + Class returnType = method.getReturnType(); - private final EntityManager em; + boolean isVoid = void.class.equals(returnType) || Void.class.equals(returnType); + boolean isInt = int.class.equals(returnType) || Integer.class.equals(returnType); + Assert.isTrue(isInt || isVoid, "Modifying queries can only use void or int/Integer as return type!"); - /** - * Creates an execution that automatically clears the given - * {@link EntityManager} after execution if the given - * {@link EntityManager} is not {@literal null}. - * - * @param em - */ - public ModifyingExecution(JpaQueryMethod method, EntityManager em) { + this.em = em; + } - Class returnType = method.getReturnType(); + @Override + protected Object doExecute(AbstractJpaQuery query, Object[] values) { - boolean isVoid = - void.class.equals(returnType) - || Void.class.equals(returnType); - boolean isInt = - int.class.equals(returnType) - || Integer.class.equals(returnType); + int result = query.createQuery(values).executeUpdate(); - Assert.isTrue(isInt || isVoid, - "Modifying queries can only use void or int/Integer as return type!"); + if (em != null) { + em.clear(); + } - this.em = em; - } - - - @Override - protected Object doExecute(AbstractJpaQuery query, Object[] values) { - - int result = query.createQuery(values).executeUpdate(); - - if (em != null) { - em.clear(); - } - - return result; - } - } + return result; + } + } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java index 333194f0d..4b408e5c7 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryLookupStrategy.java @@ -28,7 +28,6 @@ import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.RepositoryQuery; - /** * Query lookup strategy to execute finders. * @@ -36,186 +35,154 @@ import org.springframework.data.repository.query.RepositoryQuery; */ public final class JpaQueryLookupStrategy { - /** - * Private constructor to prevent instantiation. - */ - private JpaQueryLookupStrategy() { + /** + * Private constructor to prevent instantiation. + */ + private JpaQueryLookupStrategy() { - } + } - /** - * Base class for {@link QueryLookupStrategy} implementations that need - * access to an {@link EntityManager}. - * - * @author Oliver Gierke - */ - private abstract static class AbstractQueryLookupStrategy implements - QueryLookupStrategy { + /** + * Base class for {@link QueryLookupStrategy} implementations that need access to an {@link EntityManager}. + * + * @author Oliver Gierke + */ + private abstract static class AbstractQueryLookupStrategy implements QueryLookupStrategy { - private final EntityManager em; - private final QueryExtractor provider; + private final EntityManager em; + private final QueryExtractor provider; + public AbstractQueryLookupStrategy(EntityManager em, QueryExtractor extractor) { - public AbstractQueryLookupStrategy(EntityManager em, - QueryExtractor extractor) { + this.em = em; + this.provider = extractor; + } - this.em = em; - this.provider = extractor; - } + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.query.QueryLookupStrategy# + * resolveQuery(java.lang.reflect.Method, + * org.springframework.data.repository.core.RepositoryMetadata, + * org.springframework.data.repository.core.NamedQueries) + */ + public final RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, NamedQueries namedQueries) { + return resolveQuery(new JpaQueryMethod(method, metadata, provider), em, namedQueries); + } - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.query.QueryLookupStrategy# - * resolveQuery(java.lang.reflect.Method, - * org.springframework.data.repository.core.RepositoryMetadata, - * org.springframework.data.repository.core.NamedQueries) - */ - public final RepositoryQuery resolveQuery(Method method, - RepositoryMetadata metadata, NamedQueries namedQueries) { + protected abstract RepositoryQuery resolveQuery(JpaQueryMethod method, EntityManager em, NamedQueries namedQueries); + } - return resolveQuery(new JpaQueryMethod(method, metadata, provider), - em, namedQueries); - } + /** + * {@link QueryLookupStrategy} to create a query from the method name. + * + * @author Oliver Gierke + */ + private static class CreateQueryLookupStrategy extends AbstractQueryLookupStrategy { + public CreateQueryLookupStrategy(EntityManager em, QueryExtractor extractor) { - protected abstract RepositoryQuery resolveQuery(JpaQueryMethod method, - EntityManager em, NamedQueries namedQueries); - } + super(em, extractor); + } - /** - * {@link QueryLookupStrategy} to create a query from the method name. - * - * @author Oliver Gierke - */ - private static class CreateQueryLookupStrategy extends - AbstractQueryLookupStrategy { + @Override + protected RepositoryQuery resolveQuery(JpaQueryMethod method, EntityManager em, NamedQueries namedQueries) { - public CreateQueryLookupStrategy(EntityManager em, - QueryExtractor extractor) { + return new PartTreeJpaQuery(method, em); + } + } - super(em, extractor); - } + /** + * {@link QueryLookupStrategy} that tries to detect a declared query declared via {@link Query} annotation followed by + * a JPA named query lookup. + * + * @author Oliver Gierke + */ + private static class DeclaredQueryLookupStrategy extends AbstractQueryLookupStrategy { + public DeclaredQueryLookupStrategy(EntityManager em, QueryExtractor extractor) { - @Override - protected RepositoryQuery resolveQuery(JpaQueryMethod method, - EntityManager em, NamedQueries namedQueries) { + super(em, extractor); + } - return new PartTreeJpaQuery(method, em); - } - } + @Override + protected RepositoryQuery resolveQuery(JpaQueryMethod method, EntityManager em, NamedQueries namedQueries) { - /** - * {@link QueryLookupStrategy} that tries to detect a declared query - * declared via {@link Query} annotation followed by a JPA named query - * lookup. - * - * @author Oliver Gierke - */ - private static class DeclaredQueryLookupStrategy extends - AbstractQueryLookupStrategy { + RepositoryQuery query = SimpleJpaQuery.fromQueryAnnotation(method, em); - public DeclaredQueryLookupStrategy(EntityManager em, - QueryExtractor extractor) { + if (null != query) { + return query; + } - super(em, extractor); - } + String name = method.getNamedQueryName(); + if (namedQueries.hasQuery(name)) { + return new SimpleJpaQuery(method, em, namedQueries.getQuery(name)); + } + query = NamedQuery.lookupFrom(method, em); - @Override - protected RepositoryQuery resolveQuery(JpaQueryMethod method, - EntityManager em, NamedQueries namedQueries) { + if (null != query) { + return query; + } - RepositoryQuery query = - SimpleJpaQuery.fromQueryAnnotation(method, em); + throw new IllegalStateException(String.format( + "Did neither find a NamedQuery nor an annotated query for method %s!", method)); + } - if (null != query) { - return query; - } + } - String name = method.getNamedQueryName(); - if (namedQueries.hasQuery(name)) { - return new SimpleJpaQuery(method, em, - namedQueries.getQuery(name)); - } + /** + * {@link QueryLookupStrategy} to try to detect a declared query first ( {@link Query}, JPA named query). In case none + * is found we fall back on query creation. + * + * @author Oliver Gierke + */ + private static class CreateIfNotFoundQueryLookupStrategy extends AbstractQueryLookupStrategy { - query = NamedQuery.lookupFrom(method, em); + private final DeclaredQueryLookupStrategy strategy; + private final CreateQueryLookupStrategy createStrategy; - if (null != query) { - return query; - } + public CreateIfNotFoundQueryLookupStrategy(EntityManager em, QueryExtractor extractor) { - throw new IllegalStateException( - String.format( - "Did neither find a NamedQuery nor an annotated query for method %s!", - method)); - } + super(em, extractor); + this.strategy = new DeclaredQueryLookupStrategy(em, extractor); + this.createStrategy = new CreateQueryLookupStrategy(em, extractor); + } - } + @Override + protected RepositoryQuery resolveQuery(JpaQueryMethod method, EntityManager em, NamedQueries namedQueries) { - /** - * {@link QueryLookupStrategy} to try to detect a declared query first ( - * {@link Query}, JPA named query). In case none is found we fall back on - * query creation. - * - * @author Oliver Gierke - */ - private static class CreateIfNotFoundQueryLookupStrategy extends - AbstractQueryLookupStrategy { + try { + return strategy.resolveQuery(method, em, namedQueries); + } catch (IllegalStateException e) { + return createStrategy.resolveQuery(method, em, namedQueries); + } + } + } - private final DeclaredQueryLookupStrategy strategy; - private final CreateQueryLookupStrategy createStrategy; + /** + * Creates a {@link QueryLookupStrategy} for the given {@link EntityManager} and {@link Key}. + * + * @param em + * @param key + * @return + */ + public static QueryLookupStrategy create(EntityManager em, Key key, QueryExtractor extractor) { + if (key == null) { + return new CreateIfNotFoundQueryLookupStrategy(em, extractor); + } - public CreateIfNotFoundQueryLookupStrategy(EntityManager em, - QueryExtractor extractor) { - - super(em, extractor); - this.strategy = new DeclaredQueryLookupStrategy(em, extractor); - this.createStrategy = new CreateQueryLookupStrategy(em, extractor); - } - - - @Override - protected RepositoryQuery resolveQuery(JpaQueryMethod method, - EntityManager em, NamedQueries namedQueries) { - - try { - return strategy.resolveQuery(method, em, namedQueries); - } catch (IllegalStateException e) { - return createStrategy.resolveQuery(method, em, namedQueries); - } - } - } - - - /** - * Creates a {@link QueryLookupStrategy} for the given {@link EntityManager} - * and {@link Key}. - * - * @param em - * @param key - * @return - */ - public static QueryLookupStrategy create(EntityManager em, Key key, - QueryExtractor extractor) { - - if (key == null) { - return new CreateIfNotFoundQueryLookupStrategy(em, extractor); - } - - switch (key) { - case CREATE: - return new CreateQueryLookupStrategy(em, extractor); - case USE_DECLARED_QUERY: - return new DeclaredQueryLookupStrategy(em, extractor); - case CREATE_IF_NOT_FOUND: - return new CreateIfNotFoundQueryLookupStrategy(em, extractor); - default: - throw new IllegalArgumentException(String.format( - "Unsupported query lookup strategy %s!", key)); - } - } + switch (key) { + case CREATE: + return new CreateQueryLookupStrategy(em, extractor); + case USE_DECLARED_QUERY: + return new DeclaredQueryLookupStrategy(em, extractor); + case CREATE_IF_NOT_FOUND: + return new CreateIfNotFoundQueryLookupStrategy(em, extractor); + default: + throw new IllegalArgumentException(String.format("Unsupported query lookup strategy %s!", key)); + } + } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java index 9fa3d5f52..7d27c7faa 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryMethod.java @@ -34,7 +34,6 @@ import org.springframework.data.repository.query.QueryMethod; import org.springframework.util.Assert; import org.springframework.util.StringUtils; - /** * JPA specific extension of {@link QueryMethod}. * @@ -42,137 +41,119 @@ import org.springframework.util.StringUtils; */ public class JpaQueryMethod extends QueryMethod { - private final QueryExtractor extractor; - private final Method method; + private final QueryExtractor extractor; + private final Method method; + /** + * Creates a {@link JpaQueryMethod}. + * + * @param method must not be {@literal null} + * @param extractor must not be {@literal null} + * @param metadata must not be {@literal null} + */ + public JpaQueryMethod(Method method, RepositoryMetadata metadata, QueryExtractor extractor) { - /** - * Creates a {@link JpaQueryMethod}. - * - * @param method must not be {@literal null} - * @param extractor must not be {@literal null} - * @param metadata must not be {@literal null} - */ - public JpaQueryMethod(Method method, RepositoryMetadata metadata, - QueryExtractor extractor) { + super(method, metadata); - super(method, metadata); + Assert.notNull(method, "Method must not be null!"); + Assert.notNull(extractor, "Query extractor must not be null!"); - Assert.notNull(method, "Method must not be null!"); - Assert.notNull(extractor, "Query extractor must not be null!"); + this.method = method; + this.extractor = extractor; - this.method = method; - this.extractor = extractor; + Assert.isTrue(!(isModifyingQuery() && getParameters().hasSpecialParameter()), + String.format("Modifying method must not contain %s!", Parameters.TYPES)); + } - Assert.isTrue(!(isModifyingQuery() && getParameters() - .hasSpecialParameter()), String.format( - "Modifying method must not contain %s!", Parameters.TYPES)); - } + /** + * Returns whether the finder is a modifying one. + * + * @return + */ + @Override + protected boolean isModifyingQuery() { + return null != method.getAnnotation(Modifying.class); + } - /** - * Returns whether the finder is a modifying one. - * - * @return - */ - @Override - protected boolean isModifyingQuery() { + /** + * Returns all {@link QueryHint}s annotated at this class. Note, that {@link QueryHints} + * + * @return + */ + List getHints() { - return null != method.getAnnotation(Modifying.class); - } + List result = new ArrayList(); + QueryHints hints = getAnnotation(method, QueryHints.class); + if (hints != null) { + result.addAll(Arrays.asList(hints.value())); + } - /** - * Returns all {@link QueryHint}s annotated at this class. Note, that - * {@link QueryHints} - * - * @return - */ - List getHints() { + return result; + } - List result = new ArrayList(); + /** + * Returns the {@link QueryExtractor}. + * + * @return + */ + QueryExtractor getQueryExtractor() { - QueryHints hints = getAnnotation(method, QueryHints.class); - if (hints != null) { - result.addAll(Arrays.asList(hints.value())); - } + return extractor; + } - return result; - } + /** + * Returns the actual return type of the method. + * + * @return + */ + Class getReturnType() { + return method.getReturnType(); + } - /** - * Returns the {@link QueryExtractor}. - * - * @return - */ - QueryExtractor getQueryExtractor() { + /** + * Returns the query string declared in a {@link Query} annotation or {@literal null} if neither the annotation found + * nor the attribute was specified. + * + * @return + */ + String getAnnotatedQuery() { - return extractor; - } + String query = (String) AnnotationUtils.getValue(getQueryAnnotation()); + return StringUtils.hasText(query) ? query : null; + } + /** + * Returns the countQuery string declared in a {@link Query} annotation or {@literal null} if neither the annotation + * found nor the attribute was specified. + * + * @return + */ + String getCountQuery() { - /** - * Returns the actual return type of the method. - * - * @return - */ - Class getReturnType() { + String countQuery = (String) AnnotationUtils.getValue(getQueryAnnotation(), "countQuery"); + return StringUtils.hasText(countQuery) ? countQuery : null; + } - return method.getReturnType(); - } + /** + * Returns whether we should clear automatically for modifying queries. + * + * @return + */ + boolean getClearAutomatically() { + return (Boolean) AnnotationUtils.getValue(method.getAnnotation(Modifying.class), "clearAutomatically"); + } - /** - * Returns the query string declared in a {@link Query} annotation or - * {@literal null} if neither the annotation found nor the attribute was - * specified. - * - * @return - */ - String getAnnotatedQuery() { + /** + * Returns the {@link Query} annotation that is applied to the method or {@code null} if none available. + * + * @return + */ + private Query getQueryAnnotation() { - String query = (String) AnnotationUtils.getValue(getQueryAnnotation()); - return StringUtils.hasText(query) ? query : null; - } - - - /** - * Returns the countQuery string declared in a {@link Query} annotation or - * {@literal null} if neither the annotation found nor the attribute was - * specified. - * - * @return - */ - String getCountQuery() { - - String countQuery = - (String) AnnotationUtils.getValue(getQueryAnnotation(), - "countQuery"); - return StringUtils.hasText(countQuery) ? countQuery : null; - } - - - /** - * Returns whether we should clear automatically for modifying queries. - * - * @return - */ - boolean getClearAutomatically() { - - return (Boolean) AnnotationUtils.getValue( - method.getAnnotation(Modifying.class), "clearAutomatically"); - } - - - /** - * Returns the {@link Query} annotation that is applied to the method or - * {@code null} if none available. - * - * @return - */ - private Query getQueryAnnotation() { - - return method.getAnnotation(Query.class); - } + return method.getAnnotation(Query.class); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/NamedQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/NamedQuery.java index be8966b60..f327074e0 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/NamedQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/NamedQuery.java @@ -25,125 +25,110 @@ import org.springframework.data.repository.query.QueryCreationException; import org.springframework.data.repository.query.QueryMethod; import org.springframework.data.repository.query.RepositoryQuery; - /** - * Implementation of {@link RepositoryQuery} based on - * {@link javax.persistence.NamedQuery}s. + * Implementation of {@link RepositoryQuery} based on {@link javax.persistence.NamedQuery}s. * * @author Oliver Gierke */ final class NamedQuery extends AbstractJpaQuery { - private static final String CANNOT_EXTRACT_QUERY = - "Your persistence provider does not support extracting the JPQL query from a " - + "named query thus you can't use Pageable inside your query method. Make sure you " - + "have a JpaDialect configured at your EntityManagerFactoryBean as this affects " - + "discovering the concrete persistence provider."; + private static final String CANNOT_EXTRACT_QUERY = "Your persistence provider does not support extracting the JPQL query from a " + + "named query thus you can't use Pageable inside your query method. Make sure you " + + "have a JpaDialect configured at your EntityManagerFactoryBean as this affects " + + "discovering the concrete persistence provider."; - private static final Logger LOG = LoggerFactory.getLogger(NamedQuery.class); + private static final Logger LOG = LoggerFactory.getLogger(NamedQuery.class); - private final String queryName; - private final QueryExtractor extractor; + private final String queryName; + private final QueryExtractor extractor; + /** + * Creates a new {@link NamedQuery}. + */ + private NamedQuery(JpaQueryMethod method, EntityManager em) { - /** - * Creates a new {@link NamedQuery}. - */ - private NamedQuery(JpaQueryMethod method, EntityManager em) { + super(method, em); - super(method, em); + this.queryName = method.getNamedQueryName(); + this.extractor = method.getQueryExtractor(); - this.queryName = method.getNamedQueryName(); - this.extractor = method.getQueryExtractor(); + Parameters parameters = method.getParameters(); - Parameters parameters = method.getParameters(); + if (parameters.hasSortParameter()) { + throw new IllegalStateException(String.format("Finder method %s is backed " + "by a NamedQuery and must " + + "not contain a sort parameter as we " + "cannot modify the query! Use @Query instead!", method)); + } - if (parameters.hasSortParameter()) { - throw new IllegalStateException(String.format( - "Finder method %s is backed " + "by a NamedQuery and must " - + "not contain a sort parameter as we " - + "cannot modify the query! Use @Query instead!", - method)); - } + if (parameters.hasPageableParameter()) { + LOG.info("Finder method {} is backed by a NamedQuery" + " but contains a Pageble parameter! Sorting deliviered " + + "via this Pageable will not be applied!", method); + } - if (parameters.hasPageableParameter()) { - LOG.info("Finder method {} is backed by a NamedQuery" - + " but contains a Pageble parameter! Sorting deliviered " - + "via this Pageable will not be applied!", method); - } + boolean weNeedToCreateCountQuery = method.getParameters().hasPageableParameter(); + boolean cantExtractQuery = !this.extractor.canExtractQuery(); - boolean weNeedToCreateCountQuery = - method.getParameters().hasPageableParameter(); - boolean cantExtractQuery = !this.extractor.canExtractQuery(); + if (weNeedToCreateCountQuery && cantExtractQuery) { + throw QueryCreationException.create(method, CANNOT_EXTRACT_QUERY); + } - if (weNeedToCreateCountQuery && cantExtractQuery) { - throw QueryCreationException.create(method, CANNOT_EXTRACT_QUERY); - } + Query query = em.createNamedQuery(queryName); - Query query = em.createNamedQuery(queryName); + // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=322579 + // until it gets fixed + if (null != query) { + query.getHints(); + } + } - // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=322579 - // until it gets fixed - if (null != query) { - query.getHints(); - } - } + /** + * Looks up a named query for the given {@link QueryMethod}. + * + * @param method + * @return + */ + public static RepositoryQuery lookupFrom(JpaQueryMethod method, EntityManager em) { + final String queryName = method.getNamedQueryName(); - /** - * Looks up a named query for the given {@link QueryMethod}. - * - * @param method - * @return - */ - public static RepositoryQuery lookupFrom(JpaQueryMethod method, - EntityManager em) { + LOG.debug("Looking up named query {}", queryName); - final String queryName = method.getNamedQueryName(); + try { + return new NamedQuery(method, em); + } catch (IllegalArgumentException e) { + return null; + } + } - LOG.debug("Looking up named query {}", queryName); + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery + * # + * createQuery(org.springframework.data.jpa.repository.query.ParameterBinder + * ) + */ + @Override + protected Query createQuery(Object[] values) { - try { - return new NamedQuery(method, em); - } catch (IllegalArgumentException e) { - return null; - } - } + Query query = getEntityManager().createNamedQuery(queryName); + return createBinder(values).bindAndPrepare(query); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery + * #createCountQuery(org.springframework.data.jpa.repository.query. + * ParameterBinder) + */ + @Override + protected Query createCountQuery(Object[] values) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery - * # - * createQuery(org.springframework.data.jpa.repository.query.ParameterBinder - * ) - */ - @Override - protected Query createQuery(Object[] values) { + Query query = createQuery(values); + String queryString = extractor.extractQueryString(query); - Query query = getEntityManager().createNamedQuery(queryName); - return createBinder(values).bindAndPrepare(query); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery - * #createCountQuery(org.springframework.data.jpa.repository.query. - * ParameterBinder) - */ - @Override - protected Query createCountQuery(Object[] values) { - - Query query = createQuery(values); - String queryString = extractor.extractQueryString(query); - - return createBinder(values).bind( - getEntityManager().createQuery( - QueryUtils.createCountQueryFor(queryString))); - } + return createBinder(values).bind(getEntityManager().createQuery(QueryUtils.createCountQueryFor(queryString))); + } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java b/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java index c1f10b87b..b8b7154e5 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java @@ -23,149 +23,133 @@ import org.springframework.data.repository.query.Parameter; import org.springframework.data.repository.query.Parameters; import org.springframework.util.Assert; - /** - * {@link ParameterBinder} is used to bind method parameters to a {@link Query}. - * This is usually done whenever an {@link AbstractJpaQuery} is executed. + * {@link ParameterBinder} is used to bind method parameters to a {@link Query}. This is usually done whenever an + * {@link AbstractJpaQuery} is executed. * * @author Oliver Gierke */ public class ParameterBinder { - private final Parameters parameters; - private final Object[] values; + private final Parameters parameters; + private final Object[] values; + /** + * Creates a new {@link ParameterBinder}. + * + * @param parameters + * @param values + */ + public ParameterBinder(Parameters parameters, Object[] values) { - /** - * Creates a new {@link ParameterBinder}. - * - * @param parameters - * @param values - */ - public ParameterBinder(Parameters parameters, Object[] values) { + Assert.notNull(parameters); + Assert.notNull(values); - Assert.notNull(parameters); - Assert.notNull(values); + Assert.isTrue(parameters.getNumberOfParameters() == values.length, "Invalid number of parameters given!"); - Assert.isTrue(parameters.getNumberOfParameters() == values.length, - "Invalid number of parameters given!"); + this.parameters = parameters; + this.values = values.clone(); + } - this.parameters = parameters; - this.values = values.clone(); - } + ParameterBinder(Parameters parameters) { + this(parameters, new Object[0]); + } - ParameterBinder(Parameters parameters) { + /** + * Returns the {@link Pageable} of the parameters, if available. Returns {@code null} otherwise. + * + * @return + */ + public Pageable getPageable() { - this(parameters, new Object[0]); - } + if (!parameters.hasPageableParameter()) { + return null; + } + return (Pageable) values[parameters.getPageableIndex()]; + } - /** - * Returns the {@link Pageable} of the parameters, if available. Returns - * {@code null} otherwise. - * - * @return - */ - public Pageable getPageable() { + /** + * Returns the sort instance to be used for query creation. Will use a {@link Sort} parameter if available or the + * {@link Sort} contained in a {@link Pageable} if available. Returns {@code null} if no {@link Sort} can be found. + * + * @return + */ + public Sort getSort() { - if (!parameters.hasPageableParameter()) { - return null; - } + if (parameters.hasSortParameter()) { + return (Sort) values[parameters.getSortIndex()]; + } - return (Pageable) values[parameters.getPageableIndex()]; - } + if (parameters.hasPageableParameter() && getPageable() != null) { + return getPageable().getSort(); + } + return null; + } - /** - * Returns the sort instance to be used for query creation. Will use a - * {@link Sort} parameter if available or the {@link Sort} contained in a - * {@link Pageable} if available. Returns {@code null} if no {@link Sort} - * can be found. - * - * @return - */ - public Sort getSort() { + /** + * Binds the parameters to the given {@link Query}. + * + * @param query + * @return + */ + public Query bind(Query query) { - if (parameters.hasSortParameter()) { - return (Sort) values[parameters.getSortIndex()]; - } + int methodParameterPosition = 0; + int queryParameterPosition = 1; - if (parameters.hasPageableParameter() && getPageable() != null) { - return getPageable().getSort(); - } + for (Parameter parameter : parameters) { - return null; - } + if (parameter.isBindable()) { + Object value = values[methodParameterPosition]; + bind(query, parameter, value, queryParameterPosition++); + } - /** - * Binds the parameters to the given {@link Query}. - * - * @param query - * @return - */ - public Query bind(Query query) { + methodParameterPosition++; + } - int methodParameterPosition = 0; - int queryParameterPosition = 1; + return query; + } - for (Parameter parameter : parameters) { + protected void bind(Query query, Parameter parameter, Object value, int position) { - if (parameter.isBindable()) { + if (hasNamedParameter(query) && parameter.isNamedParameter()) { + query.setParameter(parameter.getName(), value); + } else { + query.setParameter(position, value); + } + } - Object value = values[methodParameterPosition]; - bind(query, parameter, value, queryParameterPosition++); - } + /** + * Binds the parameters to the given query and applies special parameter types (e.g. pagination). + * + * @param query + * @return + */ + public Query bindAndPrepare(Query query) { - methodParameterPosition++; - } + return bindAndPrepare(query, parameters); + } - return query; - } + private Query bindAndPrepare(Query query, Parameters parameters) { + Query result = bind(query); - protected void bind(Query query, Parameter parameter, Object value, - int position) { + if (!parameters.hasPageableParameter() || getPageable() == null) { + return result; + } - if (hasNamedParameter(query) && parameter.isNamedParameter()) { - query.setParameter(parameter.getName(), value); - } else { - query.setParameter(position, value); - } - } + result.setFirstResult(getPageable().getOffset()); + result.setMaxResults(getPageable().getPageSize()); + return result; + } - /** - * Binds the parameters to the given query and applies special parameter - * types (e.g. pagination). - * - * @param query - * @return - */ - public Query bindAndPrepare(Query query) { + boolean hasNamedParameter(Query query) { - return bindAndPrepare(query, parameters); - } - - - private Query bindAndPrepare(Query query, Parameters parameters) { - - Query result = bind(query); - - if (!parameters.hasPageableParameter() || getPageable() == null) { - return result; - } - - result.setFirstResult(getPageable().getOffset()); - result.setMaxResults(getPageable().getPageSize()); - - return result; - } - - - boolean hasNamedParameter(Query query) { - - return QueryUtils.hasNamedParameter(query); - } + return QueryUtils.hasNamedParameter(query); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java index 08c6e1fa3..7da5d921d 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java @@ -28,7 +28,6 @@ import org.springframework.data.repository.query.Parameters; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; - /** * A {@link AbstractJpaQuery} implementation based on a {@link PartTree}. * @@ -36,179 +35,157 @@ import org.springframework.data.repository.query.parser.PartTree; */ public class PartTreeJpaQuery extends AbstractJpaQuery { - private final Class domainClass; - private final PartTree tree; - private final Parameters parameters; + private final Class domainClass; + private final PartTree tree; + private final Parameters parameters; - private final QueryPreparer query; - private final QueryPreparer countQuery; + private final QueryPreparer query; + private final QueryPreparer countQuery; + /** + * Creates a new {@link PartTreeJpaQuery}. + * + * @param method + * @param em + */ + public PartTreeJpaQuery(JpaQueryMethod method, EntityManager em) { - /** - * Creates a new {@link PartTreeJpaQuery}. - * - * @param method - * @param em - */ - public PartTreeJpaQuery(JpaQueryMethod method, EntityManager em) { + super(method, em); - super(method, em); + this.domainClass = method.getEntityInformation().getJavaType(); + this.tree = new PartTree(method.getName(), domainClass); + this.parameters = method.getParameters(); - this.domainClass = method.getEntityInformation().getJavaType(); - this.tree = new PartTree(method.getName(), domainClass); - this.parameters = method.getParameters(); + this.query = new QueryPreparer(parameters.potentiallySortsDynamically()); + this.countQuery = new CountQueryPreparer(parameters.potentiallySortsDynamically()); + } - this.query = - new QueryPreparer(parameters.potentiallySortsDynamically()); - this.countQuery = - new CountQueryPreparer(parameters.potentiallySortsDynamically()); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.query.AbstractJpaQuery#createQuery + * (javax.persistence.EntityManager, + * org.springframework.data.jpa.repository.query.ParameterBinder) + */ + @Override + public Query createQuery(Object[] values) { + return query.createQuery(values); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.query.AbstractJpaQuery#createQuery - * (javax.persistence.EntityManager, - * org.springframework.data.jpa.repository.query.ParameterBinder) - */ - @Override - public Query createQuery(Object[] values) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.query.AbstractJpaQuery# + * createCountQuery(javax.persistence.EntityManager) + */ + @Override + public Query createCountQuery(Object[] values) { - return query.createQuery(values); - } + return countQuery.createQuery(values); + } + /** + * Query preparer to create {@link CriteriaQuery} instances and potentially cache them. + * + * @author Oliver Gierke + */ + private class QueryPreparer { - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.query.AbstractJpaQuery# - * createCountQuery(javax.persistence.EntityManager) - */ - @Override - public Query createCountQuery(Object[] values) { + private final CriteriaQuery query; + private final List> expressions; - return countQuery.createQuery(values); - } + public QueryPreparer(boolean recreateQueries) { - /** - * Query preparer to create {@link CriteriaQuery} instances and potentially - * cache them. - * - * @author Oliver Gierke - */ - private class QueryPreparer { + JpaQueryCreator creator = createCreator(); + this.query = recreateQueries ? null : creator.createQuery(); + this.expressions = recreateQueries ? null : creator.getParameterExpressions(); + } - private final CriteriaQuery query; - private final List> expressions; + /** + * Creates a new {@link Query} for the given parameter values. + * + * @param values + * @return + */ + public Query createQuery(Object[] values) { + CriteriaQuery criteriaQuery = query; + List> expressions = this.expressions; - public QueryPreparer(boolean recreateQueries) { + if (query == null) { + JpaQueryCreator creator = createCreator(); + criteriaQuery = creator.createQuery(getDynamicSort(values)); + expressions = creator.getParameterExpressions(); + } - JpaQueryCreator creator = createCreator(); - this.query = recreateQueries ? null : creator.createQuery(); - this.expressions = - recreateQueries ? null : creator.getParameterExpressions(); - } + TypedQuery jpaQuery = getEntityManager().createQuery(criteriaQuery); + return invokeBinding(getBinder(values, expressions), jpaQuery); + } + protected JpaQueryCreator createCreator() { - /** - * Creates a new {@link Query} for the given parameter values. - * - * @param values - * @return - */ - public Query createQuery(Object[] values) { + return new JpaQueryCreator(tree, domainClass, parameters, getEntityManager()); + } - CriteriaQuery criteriaQuery = query; - List> expressions = this.expressions; + /** + * Invokes parameter binding on the given {@link TypedQuery}. + * + * @param binder + * @param query + * @return + */ + protected Query invokeBinding(ParameterBinder binder, TypedQuery query) { - if (query == null) { - JpaQueryCreator creator = createCreator(); - criteriaQuery = creator.createQuery(getDynamicSort(values)); - expressions = creator.getParameterExpressions(); - } + return binder.bindAndPrepare(query); + } - TypedQuery jpaQuery = - getEntityManager().createQuery(criteriaQuery); - return invokeBinding(getBinder(values, expressions), jpaQuery); - } + private ParameterBinder getBinder(Object[] values, List> expressions) { + return new CriteriaQueryParameterBinder(parameters, values, expressions); + } - protected JpaQueryCreator createCreator() { + private Sort getDynamicSort(Object[] values) { - return new JpaQueryCreator(tree, domainClass, parameters, - getEntityManager()); - } + return parameters.potentiallySortsDynamically() ? new ParametersParameterAccessor(parameters, values).getSort() + : null; + } + } + /** + * Special {@link QueryPreparer} to create count queries. + * + * @author Oliver Gierke + */ + private class CountQueryPreparer extends QueryPreparer { - /** - * Invokes parameter binding on the given {@link TypedQuery}. - * - * @param binder - * @param query - * @return - */ - protected Query invokeBinding(ParameterBinder binder, - TypedQuery query) { + public CountQueryPreparer(boolean recreateQueries) { - return binder.bindAndPrepare(query); - } + super(recreateQueries); + } + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.query.PartTreeJpaQuery. + * QueryPreparer#createCreator() + */ + @Override + protected JpaQueryCreator createCreator() { - private ParameterBinder getBinder(Object[] values, - List> expressions) { + return new JpaCountQueryCreator(tree, domainClass, parameters, getEntityManager()); + } - return new CriteriaQueryParameterBinder(parameters, values, - expressions); - } + /** + * Customizes binding by skipping the pagination. + * + * @see org.springframework.data.jpa.repository.query.PartTreeJpaQuery.QueryPreparer#invokeBinding(org.springframework.data.jpa.repository.query.ParameterBinder, + * javax.persistence.TypedQuery) + */ + protected Query invokeBinding(ParameterBinder binder, javax.persistence.TypedQuery query) { - - private Sort getDynamicSort(Object[] values) { - - return parameters.potentiallySortsDynamically() ? new ParametersParameterAccessor( - parameters, values).getSort() : null; - } - } - - /** - * Special {@link QueryPreparer} to create count queries. - * - * @author Oliver Gierke - */ - private class CountQueryPreparer extends QueryPreparer { - - public CountQueryPreparer(boolean recreateQueries) { - - super(recreateQueries); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.query.PartTreeJpaQuery. - * QueryPreparer#createCreator() - */ - @Override - protected JpaQueryCreator createCreator() { - - return new JpaCountQueryCreator(tree, domainClass, parameters, - getEntityManager()); - } - - - /** - * Customizes binding by skipping the pagination. - * - * @see org.springframework.data.jpa.repository.query.PartTreeJpaQuery.QueryPreparer#invokeBinding(org.springframework.data.jpa.repository.query.ParameterBinder, - * javax.persistence.TypedQuery) - */ - protected Query invokeBinding(ParameterBinder binder, - javax.persistence.TypedQuery query) { - - return binder.bind(query); - } - } + return binder.bind(query); + } + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/QueryExtractor.java b/src/main/java/org/springframework/data/jpa/repository/query/QueryExtractor.java index 421fb1db1..fa3e930ad 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/QueryExtractor.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/QueryExtractor.java @@ -17,33 +17,26 @@ package org.springframework.data.jpa.repository.query; import javax.persistence.Query; - /** - * Interface to hide different implementations to extract the original JPA query - * string from a {@link Query}. + * Interface to hide different implementations to extract the original JPA query string from a {@link Query}. * * @author Oliver Gierke */ public interface QueryExtractor { - /** - * Reverse engineers the query string from the {@link Query} object. This - * requires provider specific API as JPA does not provide access to the - * underlying query string as soon as one has created a {@link Query} - * instance of it. - * - * @param query - * @return the query string representing the query or {@literal null} if - * resolving is not possible. - */ - String extractQueryString(Query query); + /** + * Reverse engineers the query string from the {@link Query} object. This requires provider specific API as JPA does + * not provide access to the underlying query string as soon as one has created a {@link Query} instance of it. + * + * @param query + * @return the query string representing the query or {@literal null} if resolving is not possible. + */ + String extractQueryString(Query query); - - /** - * Returns whether the extractor is able to extract the original query - * string from a given {@link Query}. - * - * @return - */ - boolean canExtractQuery(); + /** + * Returns whether the extractor is able to extract the original query string from a given {@link Query}. + * + * @return + */ + boolean canExtractQuery(); } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java b/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java index b1d385741..25bc6089e 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java @@ -36,7 +36,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.util.Assert; - /** * Simple utility class to create JPA queries. * @@ -44,273 +43,251 @@ import org.springframework.util.Assert; */ public abstract class QueryUtils { - public static final String COUNT_QUERY_STRING = - "select count(%s) from %s x"; + public static final String COUNT_QUERY_STRING = "select count(%s) from %s x"; - public static final String DELETE_ALL_QUERY_STRING = "delete from %s x"; - public static final String READ_ALL_QUERY = "select x from %s x"; - private static final String DEFAULT_ALIAS = "x"; - private static final String COUNT_REPLACEMENT = "select count($3$5) $4$5$6"; + public static final String DELETE_ALL_QUERY_STRING = "delete from %s x"; + public static final String READ_ALL_QUERY = "select x from %s x"; + private static final String DEFAULT_ALIAS = "x"; + private static final String COUNT_REPLACEMENT = "select count($3$5) $4$5$6"; + + private static final Pattern ALIAS_MATCH; + private static final Pattern COUNT_MATCH; + + private static final String IDENTIFIER = "[\\p{L}._$]+"; + private static final String IDENTIFIER_GROUP = String.format("(%s)", IDENTIFIER); + + static { - private static final Pattern ALIAS_MATCH; - private static final Pattern COUNT_MATCH; + StringBuilder builder = new StringBuilder(); + builder.append("(?<=from)"); // from as starting delimiter + builder.append("(?: )+"); // at least one space separating + builder.append(IDENTIFIER_GROUP); // Entity name, can be qualified (any + builder.append("(?: as)*"); // exclude possible "as" keyword + builder.append("(?: )+"); // at least one space separating + builder.append("(\\w*)"); // the actual alias + + ALIAS_MATCH = compile(builder.toString(), CASE_INSENSITIVE); + + builder = new StringBuilder(); + builder.append("(select\\s+((distinct )?.+?)\\s+)?(from\\s+"); + builder.append(IDENTIFIER); + builder.append("(?:\\s+as)?\\s+)"); + builder.append(IDENTIFIER_GROUP); + builder.append("(.*)"); + + COUNT_MATCH = compile(builder.toString(), CASE_INSENSITIVE); + } + + /** + * Private constructor to prevent instantiation. + */ + private QueryUtils() { + + } + + /** + * Returns the query string for the given class name. + * + * @param template + * @param entityName + * @return + */ + public static String getQueryString(String template, String entityName) { - private static final String IDENTIFIER = "[\\p{L}._$]+"; - private static final String IDENTIFIER_GROUP = String.format("(%s)", - IDENTIFIER); + Assert.hasText(entityName, "Entity name must not be null or empty!"); + + return String.format(template, entityName); + } - static { + /** + * Adds {@literal order by} clause to the JPQL query. Uses the {@link #DEFAULT_ALIAS} to bind the sorting property to. + * + * @param query + * @param alias + * @param sort + * @return + */ + public static String applySorting(String query, Sort sort) { - StringBuilder builder = new StringBuilder(); - builder.append("(?<=from)"); // from as starting delimiter - builder.append("(?: )+"); // at least one space separating - builder.append(IDENTIFIER_GROUP); // Entity name, can be qualified (any - builder.append("(?: as)*"); // exclude possible "as" keyword - builder.append("(?: )+"); // at least one space separating - builder.append("(\\w*)"); // the actual alias + return applySorting(query, sort, DEFAULT_ALIAS); + } - ALIAS_MATCH = compile(builder.toString(), CASE_INSENSITIVE); + /** + * Adds {@literal order by} clause to the JPQL query. + * + * @param query + * @param sort + * @param alias + * @return + */ + public static String applySorting(String query, Sort sort, String alias) { - builder = new StringBuilder(); - builder.append("(select\\s+((distinct )?.+?)\\s+)?(from\\s+"); - builder.append(IDENTIFIER); - builder.append("(?:\\s+as)?\\s+)"); - builder.append(IDENTIFIER_GROUP); - builder.append("(.*)"); + Assert.hasText(query); - COUNT_MATCH = compile(builder.toString(), CASE_INSENSITIVE); - } - - - /** - * Private constructor to prevent instantiation. - */ - private QueryUtils() { - - } - - - /** - * Returns the query string for the given class name. - * - * @param template - * @param entityName - * @return - */ - public static String getQueryString(String template, String entityName) { - - Assert.hasText(entityName, "Entity name must not be null or empty!"); - - return String.format(template, entityName); - } - - - /** - * Adds {@literal order by} clause to the JPQL query. Uses the - * {@link #DEFAULT_ALIAS} to bind the sorting property to. - * - * @param query - * @param alias - * @param sort - * @return - */ - public static String applySorting(String query, Sort sort) { - - return applySorting(query, sort, DEFAULT_ALIAS); - } - - - /** - * Adds {@literal order by} clause to the JPQL query. - * - * @param query - * @param sort - * @param alias - * @return - */ - public static String applySorting(String query, Sort sort, String alias) { - - Assert.hasText(query); - - if (null == sort) { - return query; - } - - StringBuilder builder = new StringBuilder(query); - builder.append(" order by"); - - for (Order order : sort) { - builder.append(String.format(" %s.%s %s,", alias, - order.getProperty(), toJpaDirection(order))); - } - - builder.deleteCharAt(builder.length() - 1); - - return builder.toString(); - } - - - public static String toJpaDirection(Order order) { - - return order.getDirection().name().toLowerCase(Locale.US); - } - - - /** - * Resolves the alias for the entity to be retrieved from the given JPA - * query. - * - * @param query - * @return - */ - public static String detectAlias(String query) { - - Matcher matcher = ALIAS_MATCH.matcher(query); - - return matcher.find() ? matcher.group(2) : null; - } - - - /** - * Creates a where-clause referencing the given entities and appends it to - * the given query string. Binds the given entities to the query. - * - * @param - * @param queryString - * @param entities - * @param entityManager - * @return - */ - public static Query applyAndBind(String queryString, - Iterable entities, EntityManager entityManager) { - - Assert.notNull(queryString); - Assert.notNull(entities); - Assert.notNull(entityManager); - - Iterator iterator = entities.iterator(); - - if (!iterator.hasNext()) { - return entityManager.createQuery(queryString); - } - - String alias = detectAlias(queryString); - StringBuilder builder = new StringBuilder(queryString); - builder.append(" where"); - - int i = 0; - - while (iterator.hasNext()) { - - iterator.next(); - - builder.append(String.format(" %s = ?%d", alias, ++i)); - - if (iterator.hasNext()) { - builder.append(" or"); - } - } - - Query query = entityManager.createQuery(builder.toString()); - - iterator = entities.iterator(); - i = 0; - - while (iterator.hasNext()) { - query.setParameter(++i, iterator.next()); - } - - return query; - } - - - /** - * Creates a count projected query from the given orginal query. - * - * @param originalQuery must not be {@literal null} or empty - * @return - */ - public static String createCountQueryFor(String originalQuery) { - - Assert.hasText(originalQuery); - - Matcher matcher = COUNT_MATCH.matcher(originalQuery); - return matcher.replaceFirst(COUNT_REPLACEMENT); - } - - - /** - * Returns whether the given {@link Query} contains named parameters. - * - * @param query - * @return - */ - public static boolean hasNamedParameter(Query query) { - - for (Parameter parameter : query.getParameters()) { - if (parameter.getName() != null) { - return true; - } - } - - return false; - } - - - /** - * Turns the given {@link Sort} into - * {@link javax.persistence.criteria.Order}s. - * - * @param sort - * @param root - * @param cb - * @return - */ - public static List toOrders(Sort sort, - Root root, CriteriaBuilder cb) { - - List orders = - new ArrayList(); - - if (sort == null) { - return orders; - } - - for (org.springframework.data.domain.Sort.Order order : sort) { - orders.add(toJpaOrder(order, root, cb)); - } - - return orders; - } - - - /** - * Creates a criteria API {@link javax.persistence.criteria.Order} from the - * given {@link Order}. - * - * @param order - * @param root - * @param cb - * @return - */ - private static javax.persistence.criteria.Order toJpaOrder(Order order, - Root root, CriteriaBuilder cb) { - - Expression expression = null; - String pathString = order.getProperty(); - String[] pathElements = pathString.split("\\."); - int pathSize = pathElements.length; - - if (pathSize > 1) { - Join path = root.join(pathElements[0]); - for (int i = 1; i < pathSize - 1; i++) { - path = path.join(pathElements[i]); - } - expression = path.get(pathElements[pathSize - 1]); - } else { - expression = root.get(pathString); - } - - return order.isAscending() ? cb.asc(expression) : cb.desc(expression); - } + if (null == sort) { + return query; + } + + StringBuilder builder = new StringBuilder(query); + builder.append(" order by"); + + for (Order order : sort) { + builder.append(String.format(" %s.%s %s,", alias, order.getProperty(), toJpaDirection(order))); + } + + builder.deleteCharAt(builder.length() - 1); + + return builder.toString(); + } + + public static String toJpaDirection(Order order) { + + return order.getDirection().name().toLowerCase(Locale.US); + } + + /** + * Resolves the alias for the entity to be retrieved from the given JPA query. + * + * @param query + * @return + */ + public static String detectAlias(String query) { + + Matcher matcher = ALIAS_MATCH.matcher(query); + + return matcher.find() ? matcher.group(2) : null; + } + + /** + * Creates a where-clause referencing the given entities and appends it to the given query string. Binds the given + * entities to the query. + * + * @param + * @param queryString + * @param entities + * @param entityManager + * @return + */ + public static Query applyAndBind(String queryString, Iterable entities, EntityManager entityManager) { + + Assert.notNull(queryString); + Assert.notNull(entities); + Assert.notNull(entityManager); + + Iterator iterator = entities.iterator(); + + if (!iterator.hasNext()) { + return entityManager.createQuery(queryString); + } + + String alias = detectAlias(queryString); + StringBuilder builder = new StringBuilder(queryString); + builder.append(" where"); + + int i = 0; + + while (iterator.hasNext()) { + + iterator.next(); + + builder.append(String.format(" %s = ?%d", alias, ++i)); + + if (iterator.hasNext()) { + builder.append(" or"); + } + } + + Query query = entityManager.createQuery(builder.toString()); + + iterator = entities.iterator(); + i = 0; + + while (iterator.hasNext()) { + query.setParameter(++i, iterator.next()); + } + + return query; + } + + /** + * Creates a count projected query from the given orginal query. + * + * @param originalQuery must not be {@literal null} or empty + * @return + */ + public static String createCountQueryFor(String originalQuery) { + + Assert.hasText(originalQuery); + + Matcher matcher = COUNT_MATCH.matcher(originalQuery); + return matcher.replaceFirst(COUNT_REPLACEMENT); + } + + /** + * Returns whether the given {@link Query} contains named parameters. + * + * @param query + * @return + */ + public static boolean hasNamedParameter(Query query) { + + for (Parameter parameter : query.getParameters()) { + if (parameter.getName() != null) { + return true; + } + } + + return false; + } + + /** + * Turns the given {@link Sort} into {@link javax.persistence.criteria.Order}s. + * + * @param sort + * @param root + * @param cb + * @return + */ + public static List toOrders(Sort sort, Root root, CriteriaBuilder cb) { + + List orders = new ArrayList(); + + if (sort == null) { + return orders; + } + + for (org.springframework.data.domain.Sort.Order order : sort) { + orders.add(toJpaOrder(order, root, cb)); + } + + return orders; + } + + /** + * Creates a criteria API {@link javax.persistence.criteria.Order} from the given {@link Order}. + * + * @param order + * @param root + * @param cb + * @return + */ + private static javax.persistence.criteria.Order toJpaOrder(Order order, Root root, CriteriaBuilder cb) { + + Expression expression = null; + String pathString = order.getProperty(); + String[] pathElements = pathString.split("\\."); + int pathSize = pathElements.length; + + if (pathSize > 1) { + Join path = root.join(pathElements[0]); + for (int i = 1; i < pathSize - 1; i++) { + path = path.join(pathElements[i]); + } + expression = path.get(pathElements[pathSize - 1]); + } else { + expression = root.get(pathString); + } + + return order.isAscending() ? cb.asc(expression) : cb.desc(expression); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java index 0fe924b4a..1157eb7d6 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/SimpleJpaQuery.java @@ -29,117 +29,99 @@ import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.QueryMethod; import org.springframework.data.repository.query.RepositoryQuery; - /** - * {@link RepositoryQuery} implementation that inspects a {@link QueryMethod} - * for the existanve of an {@link org.springframework.data.jpa.repository.Query} - * annotation and creates a JPA {@link Query} from it. + * {@link RepositoryQuery} implementation that inspects a {@link QueryMethod} for the existanve of an + * {@link org.springframework.data.jpa.repository.Query} annotation and creates a JPA {@link Query} from it. * * @author Oliver Gierke */ final class SimpleJpaQuery extends AbstractJpaQuery { - private static final Logger LOG = LoggerFactory - .getLogger(SimpleJpaQuery.class); + private static final Logger LOG = LoggerFactory.getLogger(SimpleJpaQuery.class); - private final String queryString; - private final String countQuery; - private final String alias; - private final List hints; - private final Parameters parameters; + private final String queryString; + private final String countQuery; + private final String alias; + private final List hints; + private final Parameters parameters; + /** + * Creates a new {@link SimpleJpaQuery} that encapsulates a simple query string. + */ + SimpleJpaQuery(JpaQueryMethod method, EntityManager em, String queryString) { - /** - * Creates a new {@link SimpleJpaQuery} that encapsulates a simple query - * string. - */ - SimpleJpaQuery(JpaQueryMethod method, EntityManager em, String queryString) { + super(method, em); + this.queryString = queryString; + this.alias = QueryUtils.detectAlias(queryString); + this.hints = method.getHints(); + this.parameters = method.getParameters(); + this.countQuery = method.getCountQuery() == null ? QueryUtils.createCountQueryFor(queryString) : method + .getCountQuery(); - super(method, em); - this.queryString = queryString; - this.alias = QueryUtils.detectAlias(queryString); - this.hints = method.getHints(); - this.parameters = method.getParameters(); - this.countQuery = - method.getCountQuery() == null ? QueryUtils - .createCountQueryFor(queryString) : method - .getCountQuery(); + // Try to create a + em.createQuery(queryString); + } - // Try to create a - em.createQuery(queryString); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery + * # + * createQuery(org.springframework.data.jpa.repository.query.ParameterBinder + * ) + */ + @Override + public Query createQuery(Object[] values) { + ParameterAccessor accessor = new ParametersParameterAccessor(parameters, values); + String sortedQueryString = QueryUtils.applySorting(queryString, accessor.getSort(), alias); - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery - * # - * createQuery(org.springframework.data.jpa.repository.query.ParameterBinder - * ) - */ - @Override - public Query createQuery(Object[] values) { + Query query = getEntityManager().createQuery(sortedQueryString); + return createBinder(values).bindAndPrepare(applyHints(query)); + } - ParameterAccessor accessor = - new ParametersParameterAccessor(parameters, values); - String sortedQueryString = - QueryUtils.applySorting(queryString, accessor.getSort(), alias); + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.query.AbstractJpaQuery# + * createCountQuery(java.lang.Object[]) + */ + @Override + protected Query createCountQuery(Object[] values) { - Query query = getEntityManager().createQuery(sortedQueryString); - return createBinder(values).bindAndPrepare(applyHints(query)); - } + return createBinder(values).bind(applyHints(getEntityManager().createQuery(countQuery))); + } + /** + * Applies the declared query hints to the given query. + * + * @param query + * @return + */ + private Query applyHints(Query query) { - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.query.AbstractJpaQuery# - * createCountQuery(java.lang.Object[]) - */ - @Override - protected Query createCountQuery(Object[] values) { + for (QueryHint hint : hints) { + query.setHint(hint.name(), hint.value()); + } - return createBinder(values).bind( - applyHints(getEntityManager().createQuery(countQuery))); - } + return query; + } + /** + * Creates a {@link RepositoryQuery} from the given {@link QueryMethod} that is potentially annotated with + * {@link org.springframework.data.jpa.repository.Query}. + * + * @param queryMethod + * @param em + * @return the {@link RepositoryQuery} derived from the annotation or {@code null} if no annotation found. + */ + public static RepositoryQuery fromQueryAnnotation(JpaQueryMethod queryMethod, EntityManager em) { - /** - * Applies the declared query hints to the given query. - * - * @param query - * @return - */ - private Query applyHints(Query query) { + LOG.debug("Looking up query for method {}", queryMethod.getName()); - for (QueryHint hint : hints) { - query.setHint(hint.name(), hint.value()); - } + String query = queryMethod.getAnnotatedQuery(); - return query; - } - - - /** - * Creates a {@link RepositoryQuery} from the given {@link QueryMethod} that - * is potentially annotated with - * {@link org.springframework.data.jpa.repository.Query}. - * - * @param queryMethod - * @param em - * @return the {@link RepositoryQuery} derived from the annotation or - * {@code null} if no annotation found. - */ - public static RepositoryQuery fromQueryAnnotation( - JpaQueryMethod queryMethod, EntityManager em) { - - LOG.debug("Looking up query for method {}", queryMethod.getName()); - - String query = queryMethod.getAnnotatedQuery(); - - return query == null ? null - : new SimpleJpaQuery(queryMethod, em, query); - } + return query == null ? null : new SimpleJpaQuery(queryMethod, em, query); + } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java index 674ef7c52..801884467 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformation.java @@ -21,28 +21,24 @@ import javax.persistence.metamodel.SingularAttribute; import org.springframework.data.repository.core.EntityInformation; - /** - * Extension of {@link EntityInformation} to capture aditional JPA specific - * information about entities. + * Extension of {@link EntityInformation} to capture aditional JPA specific information about entities. * * @author Oliver Gierke */ -public interface JpaEntityInformation extends - EntityInformation { +public interface JpaEntityInformation extends EntityInformation { - /** - * Returns the id attribute of the entity. - * - * @return - */ - SingularAttribute getIdAttribute(); + /** + * Returns the id attribute of the entity. + * + * @return + */ + SingularAttribute getIdAttribute(); - - /** - * Returns the JPA entity name. - * - * @return - */ - String getEntityName(); + /** + * Returns the JPA entity name. + * + * @return + */ + String getEntityName(); } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java index e8d3696e3..887414474 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupport.java @@ -25,68 +25,60 @@ import org.springframework.data.domain.Persistable; import org.springframework.data.repository.core.support.AbstractEntityInformation; import org.springframework.util.StringUtils; - /** - * Base class for {@link JpaEntityInformation} implementations to share common - * method implementations. + * Base class for {@link JpaEntityInformation} implementations to share common method implementations. * * @author Oliver Gierke */ -public abstract class JpaEntityInformationSupport - extends AbstractEntityInformation implements - JpaEntityInformation { +public abstract class JpaEntityInformationSupport extends AbstractEntityInformation + implements JpaEntityInformation { - /** - * Creates a new {@link JpaEntityInformationSupport} with the given domain - * class. - * - * @param domainClass - */ - public JpaEntityInformationSupport(Class domainClass) { + /** + * Creates a new {@link JpaEntityInformationSupport} with the given domain class. + * + * @param domainClass + */ + public JpaEntityInformationSupport(Class domainClass) { - super(domainClass); - } + super(domainClass); + } + /** + * Creates a {@link JpaEntityInformation} for the given domain class and {@link EntityManager}. + * + * @param domainClass + * @param em + * @return + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static JpaEntityInformation getMetadata(Class domainClass, EntityManager em) { - /** - * Creates a {@link JpaEntityInformation} for the given domain class and - * {@link EntityManager}. - * - * @param domainClass - * @param em - * @return - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static JpaEntityInformation getMetadata( - Class domainClass, EntityManager em) { + Metamodel metamodel = em.getMetamodel(); - Metamodel metamodel = em.getMetamodel(); + if (Persistable.class.isAssignableFrom(domainClass)) { + return new JpaPersistableEntityInformation(domainClass, metamodel); + } else { + try { + return new JpaMetamodelEntityInformation(domainClass, metamodel); + } catch (IllegalArgumentException e) { + return null; + } + } + } - if (Persistable.class.isAssignableFrom(domainClass)) { - return new JpaPersistableEntityInformation(domainClass, metamodel); - } else { - try { - return new JpaMetamodelEntityInformation(domainClass, metamodel); - } catch (IllegalArgumentException e) { - return null; - } - } - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.support.JpaEntityInformation# + * getEntityName() + */ + public String getEntityName() { + Class domainClass = getJavaType(); + Entity entity = domainClass.getAnnotation(Entity.class); + boolean hasName = null != entity && StringUtils.hasText(entity.name()); - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.support.JpaEntityInformation# - * getEntityName() - */ - public String getEntityName() { - - Class domainClass = getJavaType(); - Entity entity = domainClass.getAnnotation(Entity.class); - boolean hasName = null != entity && StringUtils.hasText(entity.name()); - - return hasName ? entity.name() : domainClass.getSimpleName(); - } + return hasName ? entity.name() : domainClass.getSimpleName(); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java index b0eeddfb9..e98d92d96 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaMetamodelEntityInformation.java @@ -28,104 +28,91 @@ import org.springframework.data.repository.core.EntityInformation; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; - /** - * Implementation of {@link EntityInformation} that uses JPA {@link Metamodel} - * to find the domain class' id field. + * Implementation of {@link EntityInformation} that uses JPA {@link Metamodel} to find the domain class' id field. * * @author Oliver Gierke */ -public class JpaMetamodelEntityInformation extends - JpaEntityInformationSupport implements - JpaEntityInformation { +public class JpaMetamodelEntityInformation extends JpaEntityInformationSupport + implements JpaEntityInformation { - private final SingularAttribute attribute; + private final SingularAttribute attribute; + /** + * Creates a new {@link JpaMetamodelEntityInformation} for the given domain class and {@link Metamodel}. + * + * @param domainClass + * @param metamodel + */ + public JpaMetamodelEntityInformation(Class domainClass, Metamodel metamodel) { - /** - * Creates a new {@link JpaMetamodelEntityInformation} for the given domain - * class and {@link Metamodel}. - * - * @param domainClass - * @param metamodel - */ - public JpaMetamodelEntityInformation(Class domainClass, - Metamodel metamodel) { + super(domainClass); - super(domainClass); + Assert.notNull(metamodel); + EntityType type = metamodel.entity(domainClass); - Assert.notNull(metamodel); - EntityType type = metamodel.entity(domainClass); + if (type == null) { + throw new IllegalArgumentException("The given domain class can not be found in the given Metamodel!"); + } - if (type == null) { - throw new IllegalArgumentException( - "The given domain class can not be found in the given Metamodel!"); - } + this.attribute = type.getId(type.getIdType().getJavaType()); + } - this.attribute = type.getId(type.getIdType().getJavaType()); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.IdAware#getId(java.lang.Object + * ) + */ + @SuppressWarnings("unchecked") + public ID getId(T entity) { + return (ID) getMemberValue(attribute.getJavaMember(), entity); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.IdAware#getId(java.lang.Object - * ) - */ - @SuppressWarnings("unchecked") - public ID getId(T entity) { + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.EntityInformation#getIdType() + */ + @SuppressWarnings("unchecked") + public Class getIdType() { - return (ID) getMemberValue(attribute.getJavaMember(), entity); - } + return (Class) attribute.getJavaType(); + } + /** + * Returns the value of the given {@link Member} of the given {@link Object} . + * + * @param member + * @param source + * @return + */ + private static Object getMemberValue(Member member, Object source) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.EntityInformation#getIdType() - */ - @SuppressWarnings("unchecked") - public Class getIdType() { + if (member instanceof Field) { + Field field = (Field) member; + ReflectionUtils.makeAccessible(field); + return ReflectionUtils.getField(field, source); + } else if (member instanceof Method) { + Method method = (Method) member; + ReflectionUtils.makeAccessible(method); + return ReflectionUtils.invokeMethod(method, source); + } - return (Class) attribute.getJavaType(); - } + throw new IllegalArgumentException("Given member is neither Field nor Method!"); + } + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.support.JpaEntityMetadata# + * getIdAttribute() + */ + public SingularAttribute getIdAttribute() { - /** - * Returns the value of the given {@link Member} of the given {@link Object} - * . - * - * @param member - * @param source - * @return - */ - private static Object getMemberValue(Member member, Object source) { - - if (member instanceof Field) { - Field field = (Field) member; - ReflectionUtils.makeAccessible(field); - return ReflectionUtils.getField(field, source); - } else if (member instanceof Method) { - Method method = (Method) member; - ReflectionUtils.makeAccessible(method); - return ReflectionUtils.invokeMethod(method, source); - } - - throw new IllegalArgumentException( - "Given member is neither Field nor Method!"); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.support.JpaEntityMetadata# - * getIdAttribute() - */ - public SingularAttribute getIdAttribute() { - - return attribute; - } + return attribute; + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformation.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformation.java index d04e05ebe..4269ccbb0 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformation.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformation.java @@ -21,54 +21,48 @@ import javax.persistence.metamodel.Metamodel; import org.springframework.data.domain.Persistable; - /** - * Extension of {@link JpaMetamodelEntityInformation} that consideres methods of - * {@link Persistable} to lookup the id. + * Extension of {@link JpaMetamodelEntityInformation} that consideres methods of {@link Persistable} to lookup the id. * * @author Oliver Gierke */ -public class JpaPersistableEntityInformation, ID extends Serializable> - extends JpaMetamodelEntityInformation { +public class JpaPersistableEntityInformation, ID extends Serializable> extends + JpaMetamodelEntityInformation { - /** - * Creates a new {@link JpaPersistableEntityInformation} for the given - * domain class and {@link Metamodel}. - * - * @param domainClass - * @param metamodel - */ - public JpaPersistableEntityInformation(Class domainClass, - Metamodel metamodel) { + /** + * Creates a new {@link JpaPersistableEntityInformation} for the given domain class and {@link Metamodel}. + * + * @param domainClass + * @param metamodel + */ + public JpaPersistableEntityInformation(Class domainClass, Metamodel metamodel) { - super(domainClass, metamodel); - } + super(domainClass, metamodel); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.AbstractEntityInformation + * #isNew(java.lang.Object) + */ + @Override + public boolean isNew(T entity) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.AbstractEntityInformation - * #isNew(java.lang.Object) - */ - @Override - public boolean isNew(T entity) { + return entity.isNew(); + } - return entity.isNew(); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.support.JpaMetamodelEntityMetadata + * #getId(java.lang.Object) + */ + @Override + public ID getId(T entity) { - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.support.JpaMetamodelEntityMetadata - * #getId(java.lang.Object) - */ - @Override - public ID getId(T entity) { - - return entity.getId(); - } + return entity.getId(); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java index d7617f183..bfcfa5799 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java @@ -31,7 +31,6 @@ import org.springframework.data.repository.query.QueryLookupStrategy; import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.util.Assert; - /** * JPA specific generic repository factory. * @@ -39,124 +38,110 @@ import org.springframework.util.Assert; */ public class JpaRepositoryFactory extends RepositoryFactorySupport { - private final EntityManager entityManager; - private final QueryExtractor extractor; + private final EntityManager entityManager; + private final QueryExtractor extractor; + /** + * Creates a new {@link JpaRepositoryFactory}. + * + * @param entityManager must not be {@literal null} + */ + public JpaRepositoryFactory(EntityManager entityManager) { - /** - * Creates a new {@link JpaRepositoryFactory}. - * - * @param entityManager must not be {@literal null} - */ - public JpaRepositoryFactory(EntityManager entityManager) { + Assert.notNull(entityManager); + this.entityManager = entityManager; + this.extractor = PersistenceProvider.fromEntityManager(entityManager); + } - Assert.notNull(entityManager); - this.entityManager = entityManager; - this.extractor = PersistenceProvider.fromEntityManager(entityManager); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.RepositoryFactorySupport# + * getTargetRepository(java.lang.Class) + */ + @Override + protected Object getTargetRepository(RepositoryMetadata metadata) { + return getTargetRepository(metadata, entityManager); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.RepositoryFactorySupport# - * getTargetRepository(java.lang.Class) - */ - @Override - protected Object getTargetRepository(RepositoryMetadata metadata) { + /** + * Callback to create a {@link JpaRepository} instance with the given {@link EntityManager} + * + * @param + * @param + * @param entityManager + * @see #getTargetRepository(RepositoryMetadata) + * @return + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected JpaRepository getTargetRepository(RepositoryMetadata metadata, + EntityManager entityManager) { - return getTargetRepository(metadata, entityManager); - } + Class repositoryInterface = metadata.getRepositoryInterface(); + JpaEntityInformation entityInformation = getEntityInformation(metadata.getDomainClass()); + if (isQueryDslExecutor(repositoryInterface)) { + return new QueryDslJpaRepository(entityInformation, entityManager); + } else { + return new SimpleJpaRepository(entityInformation, entityManager); + } + } - /** - * Callback to create a {@link JpaRepository} instance with the given - * {@link EntityManager} - * - * @param - * @param - * @param entityManager - * @see #getTargetRepository(RepositoryMetadata) - * @return - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - protected JpaRepository getTargetRepository( - RepositoryMetadata metadata, EntityManager entityManager) { + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.RepositoryFactorySupport# + * getRepositoryBaseClass() + */ + @Override + protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - Class repositoryInterface = metadata.getRepositoryInterface(); - JpaEntityInformation entityInformation = - getEntityInformation(metadata.getDomainClass()); + if (isQueryDslExecutor(metadata.getRepositoryInterface())) { + return QueryDslJpaRepository.class; + } else { + return SimpleJpaRepository.class; + } + } - if (isQueryDslExecutor(repositoryInterface)) { - return new QueryDslJpaRepository(entityInformation, entityManager); - } else { - return new SimpleJpaRepository(entityInformation, entityManager); - } - } + /** + * Returns whether the given repository interface requires a QueryDsl specific implementation to be chosen. + * + * @param repositoryInterface + * @return + */ + private boolean isQueryDslExecutor(Class repositoryInterface) { + return QUERY_DSL_PRESENT && QueryDslPredicateExecutor.class.isAssignableFrom(repositoryInterface); + } - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.RepositoryFactorySupport# - * getRepositoryBaseClass() - */ - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.RepositoryFactorySupport# + * getQueryLookupStrategy + * (org.springframework.data.repository.query.QueryLookupStrategy.Key) + */ + @Override + protected QueryLookupStrategy getQueryLookupStrategy(Key key) { - if (isQueryDslExecutor(metadata.getRepositoryInterface())) { - return QueryDslJpaRepository.class; - } else { - return SimpleJpaRepository.class; - } - } + return JpaQueryLookupStrategy.create(entityManager, key, extractor); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.RepositoryFactorySupport# + * getEntityInformation(java.lang.Class) + */ + @Override + @SuppressWarnings("unchecked") + public JpaEntityInformation getEntityInformation(Class domainClass) { - /** - * Returns whether the given repository interface requires a QueryDsl - * specific implementation to be chosen. - * - * @param repositoryInterface - * @return - */ - private boolean isQueryDslExecutor(Class repositoryInterface) { - - return QUERY_DSL_PRESENT - && QueryDslPredicateExecutor.class - .isAssignableFrom(repositoryInterface); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.RepositoryFactorySupport# - * getQueryLookupStrategy - * (org.springframework.data.repository.query.QueryLookupStrategy.Key) - */ - @Override - protected QueryLookupStrategy getQueryLookupStrategy(Key key) { - - return JpaQueryLookupStrategy.create(entityManager, key, extractor); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.RepositoryFactorySupport# - * getEntityInformation(java.lang.Class) - */ - @Override - @SuppressWarnings("unchecked") - public JpaEntityInformation getEntityInformation( - Class domainClass) { - - return (JpaEntityInformation) JpaEntityInformationSupport - .getMetadata(domainClass, entityManager); - } + return (JpaEntityInformation) JpaEntityInformationSupport.getMetadata(domainClass, entityManager); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java index fbee369c6..469cf9936 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBean.java @@ -26,69 +26,63 @@ import org.springframework.data.repository.core.support.RepositoryFactorySupport import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport; import org.springframework.util.Assert; - /** - * Special adapter for Springs {@link FactoryBean} interface to allow easy setup - * of repository factories via Spring configuration. + * Special adapter for Springs {@link FactoryBean} interface to allow easy setup of repository factories via Spring + * configuration. * * @author Oliver Gierke * @author Eberhard Wolff * @param the type of the repository */ -public class JpaRepositoryFactoryBean, S, ID extends Serializable> - extends TransactionalRepositoryFactoryBeanSupport { +public class JpaRepositoryFactoryBean, S, ID extends Serializable> extends + TransactionalRepositoryFactoryBeanSupport { - private EntityManager entityManager; + private EntityManager entityManager; + /** + * The {@link EntityManager} to be used. + * + * @param entityManager the entityManager to set + */ + @PersistenceContext + public void setEntityManager(EntityManager entityManager) { - /** - * The {@link EntityManager} to be used. - * - * @param entityManager the entityManager to set - */ - @PersistenceContext - public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } - this.entityManager = entityManager; - } + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.support. + * TransactionalRepositoryFactoryBeanSupport#doCreateRepositoryFactory() + */ + @Override + protected RepositoryFactorySupport doCreateRepositoryFactory() { + return createRepositoryFactory(entityManager); + } - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.support. - * TransactionalRepositoryFactoryBeanSupport#doCreateRepositoryFactory() - */ - @Override - protected RepositoryFactorySupport doCreateRepositoryFactory() { + /** + * Returns a {@link RepositoryFactorySupport}. + * + * @param entityManager + * @return + */ + protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) { - return createRepositoryFactory(entityManager); - } + return new JpaRepositoryFactory(entityManager); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() + */ + @Override + public void afterPropertiesSet() { - /** - * Returns a {@link RepositoryFactorySupport}. - * - * @param entityManager - * @return - */ - protected RepositoryFactorySupport createRepositoryFactory( - EntityManager entityManager) { - - return new JpaRepositoryFactory(entityManager); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - */ - @Override - public void afterPropertiesSet() { - - Assert.notNull(entityManager, "EntityManager must not be null!"); - super.afterPropertiesSet(); - } + Assert.notNull(entityManager, "EntityManager must not be null!"); + super.afterPropertiesSet(); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/PersistenceProvider.java b/src/main/java/org/springframework/data/jpa/repository/support/PersistenceProvider.java index 9cf9c55d7..84ac5b213 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/PersistenceProvider.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/PersistenceProvider.java @@ -25,7 +25,6 @@ import org.eclipse.persistence.jpa.JpaQuery; import org.hibernate.ejb.HibernateQuery; import org.springframework.data.jpa.repository.query.QueryExtractor; - /** * Enumeration representing peristence providers to be used. * @@ -33,129 +32,119 @@ import org.springframework.data.jpa.repository.query.QueryExtractor; */ public enum PersistenceProvider implements QueryExtractor { - /** - * Hibernate persistence provider. - */ - HIBERNATE("org.hibernate.ejb.HibernateEntityManager") { + /** + * Hibernate persistence provider. + */ + HIBERNATE("org.hibernate.ejb.HibernateEntityManager") { - public String extractQueryString(Query query) { + public String extractQueryString(Query query) { - return ((HibernateQuery) query).getHibernateQuery() - .getQueryString(); - } + return ((HibernateQuery) query).getHibernateQuery().getQueryString(); + } + /** + * Return custom placeholder ({@code *}) as Hibernate does create invalid queries for count queries for objects with + * compound keys. + * + * @see HHH-4044 + * @see HHH-3096 + */ + @Override + protected String getCountQueryPlaceholder() { - /** - * Return custom placeholder ({@code *}) as Hibernate does create - * invalid queries for count queries for objects with compound keys. - * - * @see HHH-4044 - * @see HHH-3096 - */ - @Override - protected String getCountQueryPlaceholder() { + return "*"; + } + }, - return "*"; - } - }, + /** + * EclipseLink persistence provider. + */ + ECLIPSELINK("org.eclipse.persistence.jpa.JpaEntityManager") { - /** - * EclipseLink persistence provider. - */ - ECLIPSELINK("org.eclipse.persistence.jpa.JpaEntityManager") { + public String extractQueryString(Query query) { - public String extractQueryString(Query query) { + return ((JpaQuery) query).getDatabaseQuery().getJPQLString(); + } - return ((JpaQuery) query).getDatabaseQuery().getJPQLString(); - } + }, - }, + /** + * OpenJpa persistence provider. + */ + OPEN_JPA("org.apache.openjpa.persistence.OpenJPAEntityManager") { - /** - * OpenJpa persistence provider. - */ - OPEN_JPA("org.apache.openjpa.persistence.OpenJPAEntityManager") { + public String extractQueryString(Query query) { - public String extractQueryString(Query query) { + return ((OpenJPAQuery) query).getQueryString(); + } + }, - return ((OpenJPAQuery) query).getQueryString(); - } - }, + /** + * Unknown special provider. Use standard JPA. + */ + GENERIC_JPA("javax.persistence.EntityManager") { - /** - * Unknown special provider. Use standard JPA. - */ - GENERIC_JPA("javax.persistence.EntityManager") { + public String extractQueryString(Query query) { - public String extractQueryString(Query query) { + return null; + } - return null; - } + @Override + public boolean canExtractQuery() { + return false; + } + }; - @Override - public boolean canExtractQuery() { + private String entityManagerClassName; - return false; - } - }; + /** + * Creates a new {@link PersistenceProvider}. + * + * @param entityManagerClassName the name of the provider specific {@link EntityManager} implementation + */ + private PersistenceProvider(String entityManagerClassName) { - private String entityManagerClassName; + this.entityManagerClassName = entityManagerClassName; + } + /** + * Determines the {@link PersistenceProvider} from the given {@link EntityManager}. If no special one can be + * determined {@value #GENERIC_JPA} will be returned. + * + * @param em + * @return + */ + public static PersistenceProvider fromEntityManager(EntityManager em) { - /** - * Creates a new {@link PersistenceProvider}. - * - * @param entityManagerClassName the name of the provider specific - * {@link EntityManager} implementation - */ - private PersistenceProvider(String entityManagerClassName) { + for (PersistenceProvider provider : values()) { + if (isEntityManagerOfType(em, provider.entityManagerClassName)) { + return provider; + } + } - this.entityManagerClassName = entityManagerClassName; - } + return GENERIC_JPA; + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.query.QueryExtractor#canExtractQuery + * () + */ + public boolean canExtractQuery() { - /** - * Determines the {@link PersistenceProvider} from the given - * {@link EntityManager}. If no special one can be determined - * {@value #GENERIC_JPA} will be returned. - * - * @param em - * @return - */ - public static PersistenceProvider fromEntityManager(EntityManager em) { + return true; + } - for (PersistenceProvider provider : values()) { - if (isEntityManagerOfType(em, provider.entityManagerClassName)) { - return provider; - } - } + /** + * Returns the placeholder to be used for simple count queries. Default implementation returns {@code *}. + * + * @return + */ + protected String getCountQueryPlaceholder() { - return GENERIC_JPA; - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.query.QueryExtractor#canExtractQuery - * () - */ - public boolean canExtractQuery() { - - return true; - } - - - /** - * Returns the placeholder to be used for simple count queries. Default - * implementation returns {@code *}. - * - * @return - */ - protected String getCountQueryPlaceholder() { - - return "x"; - } + return "x"; + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java index 0957465d5..0fee84bdb 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepository.java @@ -37,191 +37,172 @@ import com.mysema.query.types.OrderSpecifier; import com.mysema.query.types.Predicate; import com.mysema.query.types.path.PathBuilder; - /** - * QueryDsl specific extension of {@link SimpleJpaRepository} which adds - * implementation for {@link QueryDslPredicateExecutor}. + * QueryDsl specific extension of {@link SimpleJpaRepository} which adds implementation for + * {@link QueryDslPredicateExecutor}. * * @author Oliver Gierke */ -public class QueryDslJpaRepository extends - SimpleJpaRepository implements QueryDslPredicateExecutor { +public class QueryDslJpaRepository extends SimpleJpaRepository implements + QueryDslPredicateExecutor { - private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = - SimpleEntityPathResolver.INSTANCE; + private static final EntityPathResolver DEFAULT_ENTITY_PATH_RESOLVER = SimpleEntityPathResolver.INSTANCE; - private final EntityManager em; - private final EntityPath path; - private final PathBuilder builder; + private final EntityManager em; + private final EntityPath path; + private final PathBuilder builder; + /** + * Creates a new {@link QueryDslJpaRepository} from the given domain class and {@link EntityManager}. This will use + * the {@link SimpleEntityPathResolver} to translate the given domain class into an {@link EntityPath}. + * + * @param domainClass + * @param entityManager + */ + public QueryDslJpaRepository(JpaEntityInformation entityMetadata, EntityManager entityManager) { - /** - * Creates a new {@link QueryDslJpaRepository} from the given domain class - * and {@link EntityManager}. This will use the - * {@link SimpleEntityPathResolver} to translate the given domain class into - * an {@link EntityPath}. - * - * @param domainClass - * @param entityManager - */ - public QueryDslJpaRepository(JpaEntityInformation entityMetadata, - EntityManager entityManager) { + this(entityMetadata, entityManager, DEFAULT_ENTITY_PATH_RESOLVER); + } - this(entityMetadata, entityManager, DEFAULT_ENTITY_PATH_RESOLVER); - } + /** + * Creates a new {@link QueryDslJpaRepository} from the given domain class and {@link EntityManager} and uses the + * given {@link EntityPathResolver} to translate the domain class into an {@link EntityPath}. + * + * @param domainClass + * @param entityManager + * @param resolver + */ + public QueryDslJpaRepository(JpaEntityInformation entityMetadata, EntityManager entityManager, + EntityPathResolver resolver) { + super(entityMetadata, entityManager); + this.em = entityManager; + this.path = resolver.createPath(entityMetadata.getJavaType()); + this.builder = new PathBuilder(path.getType(), path.getMetadata()); + } - /** - * Creates a new {@link QueryDslJpaRepository} from the given domain class - * and {@link EntityManager} and uses the given {@link EntityPathResolver} - * to translate the domain class into an {@link EntityPath}. - * - * @param domainClass - * @param entityManager - * @param resolver - */ - public QueryDslJpaRepository(JpaEntityInformation entityMetadata, - EntityManager entityManager, EntityPathResolver resolver) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.querydsl. + * QueryDslSpecificationExecutor#findOne(com.mysema.query.types.Predicate) + */ + public T findOne(Predicate predicate) { - super(entityMetadata, entityManager); - this.em = entityManager; - this.path = resolver.createPath(entityMetadata.getJavaType()); - this.builder = new PathBuilder(path.getType(), path.getMetadata()); - } + return createQuery(predicate).uniqueResult(path); + } + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.querydsl. + * QueryDslSpecificationExecutor#findAll(com.mysema.query.types.Predicate) + */ + public List findAll(Predicate predicate) { - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.querydsl. - * QueryDslSpecificationExecutor#findOne(com.mysema.query.types.Predicate) - */ - public T findOne(Predicate predicate) { + return createQuery(predicate).list(path); + } - return createQuery(predicate).uniqueResult(path); - } + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.querydsl. + * QueryDslSpecificationExecutor#findAll(com.mysema.query.types.Predicate, + * com.mysema.query.types.OrderSpecifier[]) + */ + public List findAll(Predicate predicate, OrderSpecifier... orders) { + return createQuery(predicate).orderBy(orders).list(path); + } - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.querydsl. - * QueryDslSpecificationExecutor#findAll(com.mysema.query.types.Predicate) - */ - public List findAll(Predicate predicate) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.querydsl. + * QueryDslSpecificationExecutor#findAll(com.mysema.query.types.Predicate, + * org.springframework.data.domain.Pageable) + */ + public Page findAll(Predicate predicate, Pageable pageable) { - return createQuery(predicate).list(path); - } + JPQLQuery countQuery = createQuery(predicate); + JPQLQuery query = applyPagination(createQuery(predicate), pageable); + return new PageImpl(query.list(path), pageable, countQuery.count()); + } - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.querydsl. - * QueryDslSpecificationExecutor#findAll(com.mysema.query.types.Predicate, - * com.mysema.query.types.OrderSpecifier[]) - */ - public List findAll(Predicate predicate, OrderSpecifier... orders) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.querydsl. + * QueryDslSpecificationExecutor#count(com.mysema.query.types.Predicate) + */ + public long count(Predicate predicate) { - return createQuery(predicate).orderBy(orders).list(path); - } + return createQuery(predicate).count(); + } + /** + * Creates a new {@link JPQLQuery} for the given {@link Predicate}. + * + * @param predicate + * @return + */ + protected JPQLQuery createQuery(Predicate... predicate) { - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.querydsl. - * QueryDslSpecificationExecutor#findAll(com.mysema.query.types.Predicate, - * org.springframework.data.domain.Pageable) - */ - public Page findAll(Predicate predicate, Pageable pageable) { + return new JPAQuery(em).from(path).where(predicate); + } - JPQLQuery countQuery = createQuery(predicate); - JPQLQuery query = applyPagination(createQuery(predicate), pageable); + /** + * Applies the given {@link Pageable} to the given {@link JPQLQuery}. + * + * @param query + * @param pageable + * @return + */ + protected JPQLQuery applyPagination(JPQLQuery query, Pageable pageable) { - return new PageImpl(query.list(path), pageable, countQuery.count()); - } + if (pageable == null) { + return query; + } + query.offset(pageable.getOffset()); + query.limit(pageable.getPageSize()); - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.querydsl. - * QueryDslSpecificationExecutor#count(com.mysema.query.types.Predicate) - */ - public long count(Predicate predicate) { + return applySorting(query, pageable.getSort()); + } - return createQuery(predicate).count(); - } + /** + * Applies sorting to the given {@link JPQLQuery}. + * + * @param query + * @param sort + * @return + */ + protected JPQLQuery applySorting(JPQLQuery query, Sort sort) { + if (sort == null) { + return query; + } - /** - * Creates a new {@link JPQLQuery} for the given {@link Predicate}. - * - * @param predicate - * @return - */ - protected JPQLQuery createQuery(Predicate... predicate) { + for (Order order : sort) { + query.orderBy(toOrder(order)); + } - return new JPAQuery(em).from(path).where(predicate); - } + return query; + } + /** + * Transforms a plain {@link Order} into a QueryDsl specific {@link OrderSpecifier}. + * + * @param order + * @return + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + protected OrderSpecifier toOrder(Order order) { - /** - * Applies the given {@link Pageable} to the given {@link JPQLQuery}. - * - * @param query - * @param pageable - * @return - */ - protected JPQLQuery applyPagination(JPQLQuery query, Pageable pageable) { + Expression property = builder.get(order.getProperty()); - if (pageable == null) { - return query; - } - - query.offset(pageable.getOffset()); - query.limit(pageable.getPageSize()); - - return applySorting(query, pageable.getSort()); - } - - - /** - * Applies sorting to the given {@link JPQLQuery}. - * - * @param query - * @param sort - * @return - */ - protected JPQLQuery applySorting(JPQLQuery query, Sort sort) { - - if (sort == null) { - return query; - } - - for (Order order : sort) { - query.orderBy(toOrder(order)); - } - - return query; - } - - - /** - * Transforms a plain {@link Order} into a QueryDsl specific - * {@link OrderSpecifier}. - * - * @param order - * @return - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - protected OrderSpecifier toOrder(Order order) { - - Expression property = builder.get(order.getProperty()); - - return new OrderSpecifier( - order.isAscending() ? com.mysema.query.types.Order.ASC - : com.mysema.query.types.Order.DESC, property); - } + return new OrderSpecifier(order.isAscending() ? com.mysema.query.types.Order.ASC + : com.mysema.query.types.Order.DESC, property); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupport.java b/src/main/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupport.java index f667db5d0..fed542497 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupport.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupport.java @@ -18,7 +18,6 @@ import com.mysema.query.types.EntityPath; import com.mysema.query.types.path.PathBuilder; import com.mysema.query.types.path.PathBuilderFactory; - /** * Base class for implementing repositories using QueryDsl library. * @@ -27,78 +26,72 @@ import com.mysema.query.types.path.PathBuilderFactory; @Repository public abstract class QueryDslRepositorySupport { - @PersistenceContext - private EntityManager entityManager; - private PathBuilderFactory builderFactory = new PathBuilderFactory(); + @PersistenceContext + private EntityManager entityManager; + private PathBuilderFactory builderFactory = new PathBuilderFactory(); + /** + * Setter to inject {@link EntityManager}. + * + * @param entityManager must not be {@literal null} + */ + @Required + public void setEntityManager(EntityManager entityManager) { - /** - * Setter to inject {@link EntityManager}. - * - * @param entityManager must not be {@literal null} - */ - @Required - public void setEntityManager(EntityManager entityManager) { + Assert.notNull(entityManager); + this.entityManager = entityManager; + } - Assert.notNull(entityManager); - this.entityManager = entityManager; - } + /** + * Callback to verify configuration. Used by containers. + */ + @PostConstruct + public void validate() { + Assert.notNull(entityManager, "EntityManager must not be null!"); + } - /** - * Callback to verify configuration. Used by containers. - */ - @PostConstruct - public void validate() { + /** + * Returns a fresh {@link JPQLQuery}. + * + * @return + */ + protected JPQLQuery from(EntityPath... paths) { - Assert.notNull(entityManager, "EntityManager must not be null!"); - } + return new JPAQuery(entityManager).from(paths); + } + /** + * Returns a fresh {@link DeleteClause}. + * + * @param path + * @return + */ + protected DeleteClause delete(EntityPath path) { - /** - * Returns a fresh {@link JPQLQuery}. - * - * @return - */ - protected JPQLQuery from(EntityPath... paths) { + return new JPADeleteClause(entityManager, path); + } - return new JPAQuery(entityManager).from(paths); - } + /** + * Returns a fresh {@link UpdateClause}. + * + * @param path + * @return + */ + protected UpdateClause update(EntityPath path) { + return new JPAUpdateClause(entityManager, path); + } - /** - * Returns a fresh {@link DeleteClause}. - * - * @param path - * @return - */ - protected DeleteClause delete(EntityPath path) { + /** + * Returns a {@link PathBuilder} for the given type. + * + * @param + * @param type + * @return + */ + protected PathBuilder getBuilder(Class type) { - return new JPADeleteClause(entityManager, path); - } - - - /** - * Returns a fresh {@link UpdateClause}. - * - * @param path - * @return - */ - protected UpdateClause update(EntityPath path) { - - return new JPAUpdateClause(entityManager, path); - } - - - /** - * Returns a {@link PathBuilder} for the given type. - * - * @param - * @param type - * @return - */ - protected PathBuilder getBuilder(Class type) { - - return builderFactory.create(type); - } + return builderFactory.create(type); + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 5790d34c4..97eb77aaf 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -40,11 +40,9 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; - /** - * Default implementation of the {@link CrudRepository} interface. This will - * offer you a more sophisticated interface than the plain {@link EntityManager} - * . + * Default implementation of the {@link CrudRepository} interface. This will offer you a more sophisticated interface + * than the plain {@link EntityManager} . * * @author Oliver Gierke * @author Eberhard Wolff @@ -53,481 +51,437 @@ import org.springframework.util.Assert; */ @org.springframework.stereotype.Repository @Transactional(readOnly = true) -public class SimpleJpaRepository implements - JpaRepository, JpaSpecificationExecutor { - - private final JpaEntityInformation entityInformation; - private final EntityManager em; - private final PersistenceProvider provider; - - - /** - * Creates a new {@link SimpleJpaRepository} to manage objects of the given - * {@link JpaEntityInformation}. - * - * @param entityInformation - * @param entityManager - */ - public SimpleJpaRepository(JpaEntityInformation entityInformation, - EntityManager entityManager) { - - Assert.notNull(entityInformation); - Assert.notNull(entityManager); - this.entityInformation = entityInformation; - this.em = entityManager; - this.provider = PersistenceProvider.fromEntityManager(entityManager); - } - - - /** - * Creates a new {@link SimpleJpaRepository} to manage objects of the given - * domain type. - * - * @param domainClass - * @param em - */ - public SimpleJpaRepository(Class domainClass, EntityManager em) { - - this(JpaEntityInformationSupport.getMetadata(domainClass, em), em); - } - - - private Class getDomainClass() { - - return entityInformation.getJavaType(); - } - - - private String getDeleteAllQueryString() { - - return getQueryString(DELETE_ALL_QUERY_STRING, - entityInformation.getEntityName()); - } - - - private String getCountQueryString() { - - String countQuery = - String.format(COUNT_QUERY_STRING, - provider.getCountQueryPlaceholder(), "%s"); - - return getQueryString(countQuery, entityInformation.getEntityName()); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.JpaRepository#delete(java.io. - * Serializable) - */ - @Transactional - public void delete(ID id) { - - delete(findOne(id)); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.Repository#delete(java.lang.Object) - */ - @Transactional - public void delete(T entity) { - - em.remove(em.contains(entity) ? entity : em.merge(entity)); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.Repository#delete(java.lang.Iterable) - */ - @Transactional - public void delete(Iterable entities) { - - if (entities == null) { - return; - } - - for (T entity : entities) { - delete(entity); - } - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.JpaRepository#deleteInBatch(java - * .lang.Iterable) - */ - @Transactional - public void deleteInBatch(Iterable entities) { - - if (null == entities || !entities.iterator().hasNext()) { - return; - } - - applyAndBind( - getQueryString(DELETE_ALL_QUERY_STRING, - entityInformation.getEntityName()), entities, em) - .executeUpdate(); - em.clear(); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.Repository#deleteAll() - */ - @Transactional - public void deleteAll() { - - em.createQuery(getDeleteAllQueryString()).executeUpdate(); - em.clear(); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.Repository#readById(java.io.Serializable - * ) - */ - public T findOne(ID id) { - - Assert.notNull(id, "The given id must not be null!"); - return em.find(getDomainClass(), id); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.Repository#exists(java.io.Serializable - * ) - */ - public boolean exists(ID id) { - - Assert.notNull(id, "The given id must not be null!"); - return null != findOne(id); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.Repository#readAll() - */ - public List findAll() { - - return getQuery(null, (Sort) null).getResultList(); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.Repository#readAll(org.springframework - * .data.domain.Sort) - */ - public List findAll(Sort sort) { - - return getQuery(null, sort).getResultList(); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.Repository#readAll(org. - * springframework.data.domain.Pageable) - */ - public Page findAll(Pageable pageable) { - - if (null == pageable) { - return new PageImpl(findAll()); - } - - return findAll(null, pageable); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.JpaRepository#findOneBy(org. - * springframework.data.jpa.domain.Specification) - */ - public T findOne(Specification spec) { - - try { - return getQuery(spec, (Sort) null).getSingleResult(); - } catch (NoResultException e) { - return null; - } - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.JpaRepository#readAll(org. - * springframework.data.jpa.domain.Specification) - */ - public List findAll(Specification spec) { - - return getQuery(spec, (Sort) null).getResultList(); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.JpaRepository#readAll(org. - * springframework.data.jpa.domain.Specification, - * org.springframework.data.domain.Pageable) - */ - public Page findAll(Specification spec, Pageable pageable) { - - TypedQuery query = getQuery(spec, pageable); - - return pageable == null ? new PageImpl(query.getResultList()) - : readPage(query, pageable, spec); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.JpaSpecificationExecutor#findAll - * (org.springframework.data.jpa.domain.Specification, - * org.springframework.data.domain.Sort) - */ - public List findAll(Specification spec, Sort sort) { - - return getQuery(spec, sort).getResultList(); - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.repository.Repository#count() - */ - public long count() { - - return em.createQuery(getCountQueryString(), Long.class) - .getSingleResult(); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.JpaSpecificationExecutor#count - * (org.springframework.data.jpa.domain.Specification) - */ - public long count(Specification spec) { - - return getCountQuery(spec).getSingleResult(); - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.Repository#save(java.lang.Object) - */ - @Transactional - public T save(T entity) { - - if (entityInformation.isNew(entity)) { - em.persist(entity); - return entity; - } else { - return em.merge(entity); - } - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.JpaRepository#saveAndFlush(java - * .lang.Object) - */ - @Transactional - public T saveAndFlush(T entity) { - - T result = save(entity); - flush(); - - return result; - } - - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.Repository#save(java.lang.Iterable) - */ - @Transactional - public List save(Iterable entities) { - - List result = new ArrayList(); - - if (entities == null) { - return result; - } - - for (T entity : entities) { - result.add(save(entity)); - } - - return result; - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.JpaRepository#flush() - */ - @Transactional - public void flush() { - - em.flush(); - } - - - /** - * Reads the given {@link TypedQuery} into a {@link Page} applying the given - * {@link Pageable} and {@link Specification}. - * - * @param query - * @param spec - * @param pageable - * @return - */ - private Page readPage(TypedQuery query, Pageable pageable, - Specification spec) { - - query.setFirstResult(pageable.getOffset()); - query.setMaxResults(pageable.getPageSize()); - - Long total = getCountQuery(spec).getSingleResult(); - - return new PageImpl(query.getResultList(), pageable, total); - } - - - /** - * Creates a new {@link TypedQuery} from the given {@link Specification}. - * - * @param spec can be {@literal null} - * @param pageable can be {@literal null} - * @return - */ - private TypedQuery getQuery(Specification spec, Pageable pageable) { - - CriteriaBuilder builder = em.getCriteriaBuilder(); - CriteriaQuery query = builder.createQuery(getDomainClass()); - - Root root = applySpecificationToCriteria(spec, query); - query.select(root); - - if (pageable != null) { - query.orderBy(toOrders(pageable.getSort(), root, builder)); - } - - return em.createQuery(query); - } - - - /** - * Creates a {@link TypedQuery} for the given {@link Specification} and - * {@link Sort}. - * - * @param spec - * @param sort - * @return - */ - private TypedQuery getQuery(Specification spec, Sort sort) { - - CriteriaBuilder builder = em.getCriteriaBuilder(); - CriteriaQuery query = builder.createQuery(getDomainClass()); - - Root root = applySpecificationToCriteria(spec, query); - query.select(root); - - if (sort != null) { - query.orderBy(toOrders(sort, root, builder)); - } - - return em.createQuery(query); - } - - - /** - * Creates a new count query for the given {@link Specification}. - * - * @param spec can be {@literal null}. - * @return - */ - private TypedQuery getCountQuery(Specification spec) { - - CriteriaBuilder builder = em.getCriteriaBuilder(); - CriteriaQuery query = builder.createQuery(Long.class); - - Root root = applySpecificationToCriteria(spec, query); - query.select(builder.count(root)).distinct(true); - - return em.createQuery(query); - } - - - /** - * Applies the given {@link Specification} to the given - * {@link CriteriaQuery}. - * - * @param spec can be {@literal null} - * @param query - * @return - */ - private Root applySpecificationToCriteria(Specification spec, - CriteriaQuery query) { - - Assert.notNull(query); - Root root = query.from(getDomainClass()); - - if (spec == null) { - return root; - } - - CriteriaBuilder builder = em.getCriteriaBuilder(); - Predicate predicate = spec.toPredicate(root, query, builder); - - if (predicate != null) { - query.where(predicate); - } - - return root; - } +public class SimpleJpaRepository implements JpaRepository, + JpaSpecificationExecutor { + + private final JpaEntityInformation entityInformation; + private final EntityManager em; + private final PersistenceProvider provider; + + /** + * Creates a new {@link SimpleJpaRepository} to manage objects of the given {@link JpaEntityInformation}. + * + * @param entityInformation + * @param entityManager + */ + public SimpleJpaRepository(JpaEntityInformation entityInformation, EntityManager entityManager) { + + Assert.notNull(entityInformation); + Assert.notNull(entityManager); + this.entityInformation = entityInformation; + this.em = entityManager; + this.provider = PersistenceProvider.fromEntityManager(entityManager); + } + + /** + * Creates a new {@link SimpleJpaRepository} to manage objects of the given domain type. + * + * @param domainClass + * @param em + */ + public SimpleJpaRepository(Class domainClass, EntityManager em) { + + this(JpaEntityInformationSupport.getMetadata(domainClass, em), em); + } + + private Class getDomainClass() { + + return entityInformation.getJavaType(); + } + + private String getDeleteAllQueryString() { + + return getQueryString(DELETE_ALL_QUERY_STRING, entityInformation.getEntityName()); + } + + private String getCountQueryString() { + + String countQuery = String.format(COUNT_QUERY_STRING, provider.getCountQueryPlaceholder(), "%s"); + + return getQueryString(countQuery, entityInformation.getEntityName()); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.JpaRepository#delete(java.io. + * Serializable) + */ + @Transactional + public void delete(ID id) { + + delete(findOne(id)); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.Repository#delete(java.lang.Object) + */ + @Transactional + public void delete(T entity) { + + em.remove(em.contains(entity) ? entity : em.merge(entity)); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.Repository#delete(java.lang.Iterable) + */ + @Transactional + public void delete(Iterable entities) { + + if (entities == null) { + return; + } + + for (T entity : entities) { + delete(entity); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.JpaRepository#deleteInBatch(java + * .lang.Iterable) + */ + @Transactional + public void deleteInBatch(Iterable entities) { + + if (null == entities || !entities.iterator().hasNext()) { + return; + } + + applyAndBind(getQueryString(DELETE_ALL_QUERY_STRING, entityInformation.getEntityName()), entities, em) + .executeUpdate(); + em.clear(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.Repository#deleteAll() + */ + @Transactional + public void deleteAll() { + + em.createQuery(getDeleteAllQueryString()).executeUpdate(); + em.clear(); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.Repository#readById(java.io.Serializable + * ) + */ + public T findOne(ID id) { + + Assert.notNull(id, "The given id must not be null!"); + return em.find(getDomainClass(), id); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.Repository#exists(java.io.Serializable + * ) + */ + public boolean exists(ID id) { + + Assert.notNull(id, "The given id must not be null!"); + return null != findOne(id); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.Repository#readAll() + */ + public List findAll() { + + return getQuery(null, (Sort) null).getResultList(); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.Repository#readAll(org.springframework + * .data.domain.Sort) + */ + public List findAll(Sort sort) { + + return getQuery(null, sort).getResultList(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.Repository#readAll(org. + * springframework.data.domain.Pageable) + */ + public Page findAll(Pageable pageable) { + + if (null == pageable) { + return new PageImpl(findAll()); + } + + return findAll(null, pageable); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.JpaRepository#findOneBy(org. + * springframework.data.jpa.domain.Specification) + */ + public T findOne(Specification spec) { + + try { + return getQuery(spec, (Sort) null).getSingleResult(); + } catch (NoResultException e) { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.JpaRepository#readAll(org. + * springframework.data.jpa.domain.Specification) + */ + public List findAll(Specification spec) { + + return getQuery(spec, (Sort) null).getResultList(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.JpaRepository#readAll(org. + * springframework.data.jpa.domain.Specification, + * org.springframework.data.domain.Pageable) + */ + public Page findAll(Specification spec, Pageable pageable) { + + TypedQuery query = getQuery(spec, pageable); + + return pageable == null ? new PageImpl(query.getResultList()) : readPage(query, pageable, spec); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.JpaSpecificationExecutor#findAll + * (org.springframework.data.jpa.domain.Specification, + * org.springframework.data.domain.Sort) + */ + public List findAll(Specification spec, Sort sort) { + + return getQuery(spec, sort).getResultList(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.repository.Repository#count() + */ + public long count() { + + return em.createQuery(getCountQueryString(), Long.class).getSingleResult(); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.JpaSpecificationExecutor#count + * (org.springframework.data.jpa.domain.Specification) + */ + public long count(Specification spec) { + + return getCountQuery(spec).getSingleResult(); + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.Repository#save(java.lang.Object) + */ + @Transactional + public T save(T entity) { + + if (entityInformation.isNew(entity)) { + em.persist(entity); + return entity; + } else { + return em.merge(entity); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.JpaRepository#saveAndFlush(java + * .lang.Object) + */ + @Transactional + public T saveAndFlush(T entity) { + + T result = save(entity); + flush(); + + return result; + } + + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.Repository#save(java.lang.Iterable) + */ + @Transactional + public List save(Iterable entities) { + + List result = new ArrayList(); + + if (entities == null) { + return result; + } + + for (T entity : entities) { + result.add(save(entity)); + } + + return result; + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.JpaRepository#flush() + */ + @Transactional + public void flush() { + + em.flush(); + } + + /** + * Reads the given {@link TypedQuery} into a {@link Page} applying the given {@link Pageable} and + * {@link Specification}. + * + * @param query + * @param spec + * @param pageable + * @return + */ + private Page readPage(TypedQuery query, Pageable pageable, Specification spec) { + + query.setFirstResult(pageable.getOffset()); + query.setMaxResults(pageable.getPageSize()); + + Long total = getCountQuery(spec).getSingleResult(); + + return new PageImpl(query.getResultList(), pageable, total); + } + + /** + * Creates a new {@link TypedQuery} from the given {@link Specification}. + * + * @param spec can be {@literal null} + * @param pageable can be {@literal null} + * @return + */ + private TypedQuery getQuery(Specification spec, Pageable pageable) { + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(getDomainClass()); + + Root root = applySpecificationToCriteria(spec, query); + query.select(root); + + if (pageable != null) { + query.orderBy(toOrders(pageable.getSort(), root, builder)); + } + + return em.createQuery(query); + } + + /** + * Creates a {@link TypedQuery} for the given {@link Specification} and {@link Sort}. + * + * @param spec + * @param sort + * @return + */ + private TypedQuery getQuery(Specification spec, Sort sort) { + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(getDomainClass()); + + Root root = applySpecificationToCriteria(spec, query); + query.select(root); + + if (sort != null) { + query.orderBy(toOrders(sort, root, builder)); + } + + return em.createQuery(query); + } + + /** + * Creates a new count query for the given {@link Specification}. + * + * @param spec can be {@literal null}. + * @return + */ + private TypedQuery getCountQuery(Specification spec) { + + CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(Long.class); + + Root root = applySpecificationToCriteria(spec, query); + query.select(builder.count(root)).distinct(true); + + return em.createQuery(query); + } + + /** + * Applies the given {@link Specification} to the given {@link CriteriaQuery}. + * + * @param spec can be {@literal null} + * @param query + * @return + */ + private Root applySpecificationToCriteria(Specification spec, CriteriaQuery query) { + + Assert.notNull(query); + Root root = query.from(getDomainClass()); + + if (spec == null) { + return root; + } + + CriteriaBuilder builder = em.getCriteriaBuilder(); + Predicate predicate = spec.toPredicate(root, query, builder); + + if (predicate != null) { + query.where(predicate); + } + + return root; + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/utils/JpaClassUtils.java b/src/main/java/org/springframework/data/jpa/repository/utils/JpaClassUtils.java index 3fa063d99..21793fc12 100644 --- a/src/main/java/org/springframework/data/jpa/repository/utils/JpaClassUtils.java +++ b/src/main/java/org/springframework/data/jpa/repository/utils/JpaClassUtils.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.utils; import javax.persistence.EntityManager; - /** * Utility class to work with classes. * @@ -25,35 +24,33 @@ import javax.persistence.EntityManager; */ public abstract class JpaClassUtils { - /** - * Private constructor to prevent instantiation. - */ - private JpaClassUtils() { + /** + * Private constructor to prevent instantiation. + */ + private JpaClassUtils() { - } + } + /** + * Returns whether the given {@link EntityManager} is of the given type. + * + * @param em + * @param type the fully qualified expected {@link EntityManager} type. + * @return + */ + @SuppressWarnings("unchecked") + public static boolean isEntityManagerOfType(EntityManager em, String type) { - /** - * Returns whether the given {@link EntityManager} is of the given type. - * - * @param em - * @param type the fully qualified expected {@link EntityManager} type. - * @return - */ - @SuppressWarnings("unchecked") - public static boolean isEntityManagerOfType(EntityManager em, String type) { + try { - try { + Class emType = (Class) Class.forName(type); - Class emType = - (Class) Class.forName(type); + emType.cast(em); - emType.cast(em); + return true; - return true; - - } catch (Exception e) { - return false; - } - } + } catch (Exception e) { + return false; + } + } } diff --git a/src/main/java/org/springframework/data/jpa/support/MergingPersistenceUnitManager.java b/src/main/java/org/springframework/data/jpa/support/MergingPersistenceUnitManager.java index f4e813d2a..bdf531d62 100644 --- a/src/main/java/org/springframework/data/jpa/support/MergingPersistenceUnitManager.java +++ b/src/main/java/org/springframework/data/jpa/support/MergingPersistenceUnitManager.java @@ -24,58 +24,50 @@ import org.slf4j.LoggerFactory; import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager; import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo; - /** - * Extends {@link DefaultPersistenceUnitManager} to merge configurations of one - * persistence unit residing in multiple {@code persistence.xml} files into one. - * This is necessary to allow the declaration of entities in seperate modules. + * Extends {@link DefaultPersistenceUnitManager} to merge configurations of one persistence unit residing in multiple + * {@code persistence.xml} files into one. This is necessary to allow the declaration of entities in seperate modules. * * @author Oliver Gierke * @see http://jira.springframework.org/browse/SPR-2598 */ -public class MergingPersistenceUnitManager extends - DefaultPersistenceUnitManager { +public class MergingPersistenceUnitManager extends DefaultPersistenceUnitManager { - private static final Logger log = LoggerFactory - .getLogger(MergingPersistenceUnitManager.class); + private static final Logger log = LoggerFactory.getLogger(MergingPersistenceUnitManager.class); + /* + * (non-Javadoc) + * + * @see + * org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager + * # + * postProcessPersistenceUnitInfo(org.springframework.orm.jpa.persistenceunit + * .MutablePersistenceUnitInfo) + */ + @Override + protected void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager - * # - * postProcessPersistenceUnitInfo(org.springframework.orm.jpa.persistenceunit - * .MutablePersistenceUnitInfo) - */ - @Override - protected void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) { + // Invoke normal post processing + super.postProcessPersistenceUnitInfo(pui); - // Invoke normal post processing - super.postProcessPersistenceUnitInfo(pui); + PersistenceUnitInfo oldPui = getPersistenceUnitInfo(pui.getPersistenceUnitName()); - PersistenceUnitInfo oldPui = - getPersistenceUnitInfo(pui.getPersistenceUnitName()); + if (oldPui != null) { + postProcessPersistenceUnitInfo(pui, oldPui); + } + } - if (oldPui != null) { - postProcessPersistenceUnitInfo(pui, oldPui); - } - } + void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui, PersistenceUnitInfo oldPui) { + for (URL url : oldPui.getJarFileUrls()) { - void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui, - PersistenceUnitInfo oldPui) { + // Add jar file url to PUI + if (!pui.getJarFileUrls().contains(url)) { + log.debug("Adding {} to persistence units", url); + pui.addJarFileUrl(url); + } + } - for (URL url : oldPui.getJarFileUrls()) { - - // Add jar file url to PUI - if (!pui.getJarFileUrls().contains(url)) { - log.debug("Adding {} to persistence units", url); - pui.addJarFileUrl(url); - } - } - - pui.addJarFileUrl(oldPui.getPersistenceUnitRootUrl()); - } + pui.addJarFileUrl(oldPui.getPersistenceUnitRootUrl()); + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/Account.java b/src/test/java/org/springframework/data/jpa/domain/sample/Account.java index a7abeea70..7cce6ef28 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/Account.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/Account.java @@ -19,12 +19,11 @@ import javax.persistence.Entity; import org.springframework.data.jpa.domain.AbstractPersistable; - /** * @author Oliver Gierke */ @Entity public class Account extends AbstractPersistable { - private static final long serialVersionUID = -5719129808165758887L; + private static final long serialVersionUID = -5719129808165758887L; } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/AuditableRole.java b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableRole.java index ee76a7e78..366d354b5 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/AuditableRole.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableRole.java @@ -19,7 +19,6 @@ import javax.persistence.Entity; import org.springframework.data.jpa.domain.AbstractAuditable; - /** * Sample auditable role entity. * @@ -28,19 +27,17 @@ import org.springframework.data.jpa.domain.AbstractAuditable; @Entity public class AuditableRole extends AbstractAuditable { - private static final long serialVersionUID = 5997359055260303863L; + private static final long serialVersionUID = 5997359055260303863L; - private String name; + private String name; + public void setName(String name) { - public void setName(String name) { + this.name = name; + } - this.name = name; - } + public String getName() { - - public String getName() { - - return name; - } + return name; + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/AuditableUser.java b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableUser.java index 5d9d50b5e..c9df3247c 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/AuditableUser.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/AuditableUser.java @@ -25,11 +25,9 @@ import javax.persistence.NamedQuery; import org.springframework.data.jpa.domain.AbstractAuditable; - /** - * Sample auditable user to demonstrate working with - * {@code AbstractAuditableEntity}. No declaration of an ID is necessary. - * Furthermore no auditing information has to be declared explicitly. + * Sample auditable user to demonstrate working with {@code AbstractAuditableEntity}. No declaration of an ID is + * necessary. Furthermore no auditing information has to be declared explicitly. * * @author Oliver Gierke */ @@ -37,56 +35,50 @@ import org.springframework.data.jpa.domain.AbstractAuditable; @NamedQuery(name = "AuditableUser.findByFirstname", query = "SELECT u FROM AuditableUser u WHERE u.firstname = ?1") public class AuditableUser extends AbstractAuditable { - private static final long serialVersionUID = 7409344446795693011L; + private static final long serialVersionUID = 7409344446795693011L; - private String firstname; + private String firstname; - @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) - private Set roles = new HashSet(); + @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) + private Set roles = new HashSet(); + public AuditableUser() { - public AuditableUser() { + this(null); + } - this(null); - } + public AuditableUser(Long id) { + this.setId(id); + } - public AuditableUser(Long id) { + /** + * Returns the firstname. + * + * @return the firstname + */ + public String getFirstname() { - this.setId(id); - } + return firstname; + } + /** + * Sets the firstname. + * + * @param firstname the firstname to set + */ + public void setFirstname(final String firstname) { - /** - * Returns the firstname. - * - * @return the firstname - */ - public String getFirstname() { + this.firstname = firstname; + } - return firstname; - } + public void addRole(AuditableRole role) { + this.roles.add(role); + } - /** - * Sets the firstname. - * - * @param firstname the firstname to set - */ - public void setFirstname(final String firstname) { + public Set getRoles() { - this.firstname = firstname; - } - - - public void addRole(AuditableRole role) { - - this.roles.add(role); - } - - - public Set getRoles() { - - return roles; - } + return roles; + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/AuditorAwareStub.java b/src/test/java/org/springframework/data/jpa/domain/sample/AuditorAwareStub.java index 2cb017e9c..34c39eabe 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/AuditorAwareStub.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/AuditorAwareStub.java @@ -19,40 +19,35 @@ import org.springframework.data.domain.AuditorAware; import org.springframework.data.jpa.repository.sample.AuditableUserRepository; import org.springframework.util.Assert; - /** - * Stub implementation for {@link AuditorAware}. Returns {@literal null} for the - * current auditor. + * Stub implementation for {@link AuditorAware}. Returns {@literal null} for the current auditor. * * @author Oliver Gierke */ public class AuditorAwareStub implements AuditorAware { - @SuppressWarnings("unused") - private final AuditableUserRepository repository; - private AuditableUser auditor; + @SuppressWarnings("unused") + private final AuditableUserRepository repository; + private AuditableUser auditor; + public AuditorAwareStub(AuditableUserRepository repository) { - public AuditorAwareStub(AuditableUserRepository repository) { + Assert.notNull(repository); + this.repository = repository; + } - Assert.notNull(repository); - this.repository = repository; - } + public void setAuditor(AuditableUser auditor) { + this.auditor = auditor; + } - public void setAuditor(AuditableUser auditor) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.AuditorAware#getCurrentAuditor() + */ + public AuditableUser getCurrentAuditor() { - this.auditor = auditor; - } - - - /* - * (non-Javadoc) - * - * @see org.springframework.data.domain.AuditorAware#getCurrentAuditor() - */ - public AuditableUser getCurrentAuditor() { - - return auditor; - } + return auditor; + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/Role.java b/src/test/java/org/springframework/data/jpa/domain/sample/Role.java index e71d0a7ed..19b77d318 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/Role.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/Role.java @@ -15,8 +15,6 @@ */ package org.springframework.data.jpa.domain.sample; - - /** * Sample domain class representing roles. Mapped with XML. * @@ -24,62 +22,57 @@ package org.springframework.data.jpa.domain.sample; */ public class Role { - private static final long serialVersionUID = -8832631113344035104L; - private static final String PREFIX = "ROLE_"; + private static final long serialVersionUID = -8832631113344035104L; + private static final String PREFIX = "ROLE_"; - private Integer id; - private String name; + private Integer id; + private String name; + /** + * Creates a new instance of {@code Role}. + */ + public Role() { - /** - * Creates a new instance of {@code Role}. - */ - public Role() { + } - } + /** + * Creates a new preconfigured {@code Role}. + * + * @param name + */ + public Role(final String name) { + this.name = name; + } - /** - * Creates a new preconfigured {@code Role}. - * - * @param name - */ - public Role(final String name) { + /** + * Returns the id. + * + * @return + */ + public Integer getId() { - this.name = name; - } + return id; + } + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { - /** - * Returns the id. - * - * @return - */ - public Integer getId() { + return PREFIX + name; + } - return id; - } + /** + * Returns whether the role is to be considered new. + * + * @return + */ + public boolean isNew() { - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - - return PREFIX + name; - } - - - /** - * Returns whether the role is to be considered new. - * - * @return - */ - public boolean isNew() { - - return id == null; - } + return id == null; + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntity.java b/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntity.java index 63efe1836..51efd9675 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntity.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntity.java @@ -18,48 +18,43 @@ package org.springframework.data.jpa.domain.sample; import javax.persistence.EmbeddedId; import javax.persistence.Entity; - /** * @author Oliver Gierke */ @Entity public class SampleEntity { - @EmbeddedId - protected SampleEntityPK id; + @EmbeddedId + protected SampleEntityPK id; + protected SampleEntity() { - protected SampleEntity() { + } - } + public SampleEntity(String first, String second) { + this.id = new SampleEntityPK(first, second); + } - public SampleEntity(String first, String second) { + @Override + public boolean equals(Object obj) { - this.id = new SampleEntityPK(first, second); - } + if (obj == this) { + return true; + } + if (!getClass().equals(obj.getClass())) { + return false; + } - @Override - public boolean equals(Object obj) { + SampleEntity that = (SampleEntity) obj; - if (obj == this) { - return true; - } + return this.id.equals(that.id); + } - if (!getClass().equals(obj.getClass())) { - return false; - } + @Override + public int hashCode() { - SampleEntity that = (SampleEntity) obj; - - return this.id.equals(that.id); - } - - - @Override - public int hashCode() { - - return id.hashCode(); - } + return id.hashCode(); + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntityPK.java b/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntityPK.java index 59962ecc3..85c69a443 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntityPK.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/SampleEntityPK.java @@ -22,67 +22,62 @@ import javax.persistence.Embeddable; import org.springframework.util.Assert; - @Embeddable public class SampleEntityPK implements Serializable { - private static final long serialVersionUID = 231060947L; + private static final long serialVersionUID = 231060947L; - @Column(nullable = false) - private String first; - @Column(nullable = false) - private String second; + @Column(nullable = false) + private String first; + @Column(nullable = false) + private String second; + public SampleEntityPK() { - public SampleEntityPK() { + this.first = null; + this.second = null; + } - this.first = null; - this.second = null; - } + public SampleEntityPK(String first, String second) { + Assert.notNull(first); + Assert.notNull(second); + this.first = first; + this.second = second; + } - public SampleEntityPK(String first, String second) { + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { - Assert.notNull(first); - Assert.notNull(second); - this.first = first; - this.second = second; - } + if (this == obj) { + return true; + } + if (!this.getClass().equals(obj.getClass())) { + return false; + } - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { + SampleEntityPK that = (SampleEntityPK) obj; - if (this == obj) { - return true; - } + return this.first.equals(that.first) && this.second.equals(that.second); + } - if (!this.getClass().equals(obj.getClass())) { - return false; - } + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { - SampleEntityPK that = (SampleEntityPK) obj; - - return this.first.equals(that.first) && this.second.equals(that.second); - } - - - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - - int result = 17; - result += 31 * first.hashCode(); - result += 31 * second.hashCode(); - return result; - } + int result = 17; + result += 31 * first.hashCode(); + result += 31 * second.hashCode(); + return result; + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/SpecialUser.java b/src/test/java/org/springframework/data/jpa/domain/sample/SpecialUser.java index 40b400e4f..1cf1c8292 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/SpecialUser.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/SpecialUser.java @@ -2,7 +2,6 @@ package org.springframework.data.jpa.domain.sample; import javax.persistence.Entity; - /** * @author Oliver Gierke */ diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/User.java b/src/test/java/org/springframework/data/jpa/domain/sample/User.java index 738ae0086..e75b75c97 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/User.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/User.java @@ -28,11 +28,9 @@ import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.NamedQuery; - /** - * Domain class representing a person emphasizing the use of - * {@code AbstractEntity}. No declaration of an id is required. The id is typed - * by the parameterizable superclass. + * Domain class representing a person emphasizing the use of {@code AbstractEntity}. No declaration of an id is + * required. The id is typed by the parameterizable superclass. * * @author Oliver Gierke */ @@ -40,260 +38,236 @@ import javax.persistence.NamedQuery; @NamedQuery(name = "User.findByEmailAddress", query = "SELECT u FROM User u WHERE u.emailAddress = ?1") public class User { - private static final long serialVersionUID = 8653688953355455933L; - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Integer id; - private String firstname; - private String lastname; - - @Column(nullable = false, unique = true) - private String emailAddress; - - @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) - private Set colleagues; - - @ManyToMany - private Set roles; - - @ManyToOne - private User manager; - - - /** - * Creates a new empty instance of {@code User}. - */ - public User() { - - this.roles = new HashSet(); - this.colleagues = new HashSet(); - } - - - /** - * Creates a new instance of {@code User} with preinitialized values for - * firstname, lastname and email address. - * - * @param firstname - * @param lastname - * @param emailAddress - */ - public User(final String firstname, final String lastname, - final String emailAddress) { - - this(); - this.firstname = firstname; - this.lastname = lastname; - this.emailAddress = emailAddress; - } - - - /** - * @return the id - */ - public Integer getId() { - - return id; - } - - - /** - * @param id the id to set - */ - public void setId(Integer id) { - - this.id = id; - } - - - /** - * Returns the firstname. - * - * @return the firstname - */ - public String getFirstname() { - - return firstname; - } - - - /** - * Sets the firstname. - * - * @param firstname the firstname to set - */ - public void setFirstname(final String firstname) { - - this.firstname = firstname; - } - - - /** - * Returns the lastname. - * - * @return the lastname - */ - public String getLastname() { - - return lastname; - } - - - /** - * Sets the lastname. - * - * @param lastname the lastname to set - */ - public void setLastname(String lastname) { - - this.lastname = lastname; - } - - - /** - * Returns the email address. - * - * @return the emailAddress - */ - public String getEmailAddress() { - - return emailAddress; - } - - - /** - * Sets the email address. - * - * @param emailAddress the emailAddress to set - */ - public void setEmailAddress(String emailAddress) { - - this.emailAddress = emailAddress; - } - - - /** - * Returns the user's roles. - * - * @return the role - */ - public Set getRole() { - - return roles; - } - - - /** - * Gives the user a role. Adding a role the user already owns is a no-op. - */ - public void addRole(Role role) { - - roles.add(role); - } - - - /** - * Revokes a role from a user. - * - * @param role - */ - public void removeRole(Role role) { - - roles.remove(role); - } - - - /** - * Returns the colleagues of the user. - * - * @return the colleagues - */ - public Set getColleagues() { - - return colleagues; - } - - - /** - * Adds a new colleague to the user. Adding the user himself as colleague is - * a no-op. - * - * @param collegue - */ - public void addColleague(User collegue) { - - // Prevent from adding the user himself as colleague. - if (this.equals(collegue)) { - return; - } - - colleagues.add(collegue); - collegue.getColleagues().add(this); - } - - - /** - * Removes a colleague from the list of colleagues. - * - * @param colleague - */ - public void removeColleague(User colleague) { - - colleagues.remove(colleague); - colleague.getColleagues().remove(this); - } - - - /** - * @return the manager - */ - public User getManager() { - - return manager; - } - - - /** - * @param manager the manager to set - */ - public void setManager(User manager) { - - this.manager = manager; - } - - - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - - if (!(obj instanceof User)) { - return false; - } - - User that = (User) obj; - - if (null == this.getId() || null == that.getId()) { - return false; - } - - return this.getId().equals(that.getId()); - } - - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - - return "User: " + getId() + ", " + getFirstname() + " " + getLastname() - + ", " + getEmailAddress(); - } + private static final long serialVersionUID = 8653688953355455933L; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Integer id; + private String firstname; + private String lastname; + + @Column(nullable = false, unique = true) + private String emailAddress; + + @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) + private Set colleagues; + + @ManyToMany + private Set roles; + + @ManyToOne + private User manager; + + /** + * Creates a new empty instance of {@code User}. + */ + public User() { + + this.roles = new HashSet(); + this.colleagues = new HashSet(); + } + + /** + * Creates a new instance of {@code User} with preinitialized values for firstname, lastname and email address. + * + * @param firstname + * @param lastname + * @param emailAddress + */ + public User(final String firstname, final String lastname, final String emailAddress) { + + this(); + this.firstname = firstname; + this.lastname = lastname; + this.emailAddress = emailAddress; + } + + /** + * @return the id + */ + public Integer getId() { + + return id; + } + + /** + * @param id the id to set + */ + public void setId(Integer id) { + + this.id = id; + } + + /** + * Returns the firstname. + * + * @return the firstname + */ + public String getFirstname() { + + return firstname; + } + + /** + * Sets the firstname. + * + * @param firstname the firstname to set + */ + public void setFirstname(final String firstname) { + + this.firstname = firstname; + } + + /** + * Returns the lastname. + * + * @return the lastname + */ + public String getLastname() { + + return lastname; + } + + /** + * Sets the lastname. + * + * @param lastname the lastname to set + */ + public void setLastname(String lastname) { + + this.lastname = lastname; + } + + /** + * Returns the email address. + * + * @return the emailAddress + */ + public String getEmailAddress() { + + return emailAddress; + } + + /** + * Sets the email address. + * + * @param emailAddress the emailAddress to set + */ + public void setEmailAddress(String emailAddress) { + + this.emailAddress = emailAddress; + } + + /** + * Returns the user's roles. + * + * @return the role + */ + public Set getRole() { + + return roles; + } + + /** + * Gives the user a role. Adding a role the user already owns is a no-op. + */ + public void addRole(Role role) { + + roles.add(role); + } + + /** + * Revokes a role from a user. + * + * @param role + */ + public void removeRole(Role role) { + + roles.remove(role); + } + + /** + * Returns the colleagues of the user. + * + * @return the colleagues + */ + public Set getColleagues() { + + return colleagues; + } + + /** + * Adds a new colleague to the user. Adding the user himself as colleague is a no-op. + * + * @param collegue + */ + public void addColleague(User collegue) { + + // Prevent from adding the user himself as colleague. + if (this.equals(collegue)) { + return; + } + + colleagues.add(collegue); + collegue.getColleagues().add(this); + } + + /** + * Removes a colleague from the list of colleagues. + * + * @param colleague + */ + public void removeColleague(User colleague) { + + colleagues.remove(colleague); + colleague.getColleagues().remove(this); + } + + /** + * @return the manager + */ + public User getManager() { + + return manager; + } + + /** + * @param manager the manager to set + */ + public void setManager(User manager) { + + this.manager = manager; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + + if (!(obj instanceof User)) { + return false; + } + + User that = (User) obj; + + if (null == this.getId() || null == that.getId()) { + return false; + } + + return this.getId().equals(that.getId()); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + + return "User: " + getId() + ", " + getFirstname() + " " + getLastname() + ", " + getEmailAddress(); + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java b/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java index 2fcb8474c..8308d08e7 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java @@ -22,7 +22,6 @@ import javax.persistence.criteria.Root; import org.springframework.data.jpa.domain.Specification; - /** * Collection of {@link Specification}s for a {@link User}. * @@ -30,61 +29,53 @@ import org.springframework.data.jpa.domain.Specification; */ public class UserSpecifications { - /** - * A {@link Specification} to match on a {@link User}'s firstname. - * - * @param firstname - * @return - */ - public static Specification userHasFirstname(final String firstname) { + /** + * A {@link Specification} to match on a {@link User}'s firstname. + * + * @param firstname + * @return + */ + public static Specification userHasFirstname(final String firstname) { - return simplePropertySpec("firstname", firstname); - } + return simplePropertySpec("firstname", firstname); + } + /** + * A {@link Specification} to match on a {@link User}'s lastname. + * + * @param firstname + * @return + */ + public static Specification userHasLastname(final String lastname) { - /** - * A {@link Specification} to match on a {@link User}'s lastname. - * - * @param firstname - * @return - */ - public static Specification userHasLastname(final String lastname) { + return simplePropertySpec("lastname", lastname); + } - return simplePropertySpec("lastname", lastname); - } + /** + * A {@link Specification} to do a like-match on a {@link User}'s firstname. + * + * @param firstname + * @return + */ + public static Specification userHasFirstnameLike(final String expression) { + return new Specification() { - /** - * A {@link Specification} to do a like-match on a {@link User}'s firstname. - * - * @param firstname - * @return - */ - public static Specification userHasFirstnameLike( - final String expression) { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { - return new Specification() { + return cb.like(root.get("firstname").as(String.class), String.format("%%%s%%", expression)); + } + }; + } - public Predicate toPredicate(Root root, - CriteriaQuery query, CriteriaBuilder cb) { + private static Specification simplePropertySpec(final String property, final Object value) { - return cb.like(root.get("firstname").as(String.class), - String.format("%%%s%%", expression)); - } - }; - } + return new Specification() { + public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder builder) { - private static Specification simplePropertySpec( - final String property, final Object value) { - - return new Specification() { - - public Predicate toPredicate(Root root, CriteriaQuery query, - CriteriaBuilder builder) { - - return builder.equal(root.get(property), value); - } - }; - } + return builder.equal(root.get(property), value); + } + }; + } } \ No newline at end of file diff --git a/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java b/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java index 5d76311da..e04e2a45c 100644 --- a/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/domain/support/AuditingBeanFactoryPostProcessorUnitTests.java @@ -26,7 +26,6 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; - /** * Unit test for {@link AuditingBeanFactoryPostProcessor}. * @@ -34,38 +33,30 @@ import org.springframework.core.io.ClassPathResource; */ public class AuditingBeanFactoryPostProcessorUnitTests { - ConfigurableListableBeanFactory beanFactory; - AuditingBeanFactoryPostProcessor processor; + ConfigurableListableBeanFactory beanFactory; + AuditingBeanFactoryPostProcessor processor; + @Before + public void setUp() { - @Before - public void setUp() { + beanFactory = new XmlBeanFactory(new ClassPathResource("auditing/" + getConfigFile())); - beanFactory = - new XmlBeanFactory(new ClassPathResource("auditing/" - + getConfigFile())); + processor = new AuditingBeanFactoryPostProcessor(); + } - processor = new AuditingBeanFactoryPostProcessor(); - } + protected String getConfigFile() { + return "auditing-bfpp-context.xml"; + } - protected String getConfigFile() { + @Test + public void testname() throws Exception { - return "auditing-bfpp-context.xml"; - } + processor.postProcessBeanFactory(beanFactory); + BeanDefinition definition = beanFactory.getBeanDefinition("entityManagerFactory"); - @Test - public void testname() throws Exception { - - processor.postProcessBeanFactory(beanFactory); - - BeanDefinition definition = - beanFactory.getBeanDefinition("entityManagerFactory"); - - assertTrue(Arrays - .asList(definition.getDependsOn()) - .contains( - AuditingBeanFactoryPostProcessor.BEAN_CONFIGURER_ASPECT_BEAN_NAME)); - } + assertTrue(Arrays.asList(definition.getDependsOn()).contains( + AuditingBeanFactoryPostProcessor.BEAN_CONFIGURER_ASPECT_BEAN_NAME)); + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerTests.java b/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerTests.java index 8294e1e25..3359092bf 100644 --- a/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerTests.java +++ b/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerTests.java @@ -32,7 +32,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; - /** * Integration test for {@link AuditingEntityListener}. * @@ -44,61 +43,55 @@ import org.springframework.transaction.annotation.Transactional; @DirtiesContext public class AuditingEntityListenerTests { - @Autowired - AuditableUserRepository repository; + @Autowired + AuditableUserRepository repository; - @Autowired - AuditorAwareStub auditorAware; + @Autowired + AuditorAwareStub auditorAware; - AuditableUser user; + AuditableUser user; + @Before + public void setUp() { - @Before - public void setUp() { + user = new AuditableUser(); + auditorAware.setAuditor(user); - user = new AuditableUser(); - auditorAware.setAuditor(user); + repository.save(user); + } - repository.save(user); - } + @Test + public void auditsRootEntityCorrectly() throws Exception { + assertDatesSet(user); + assertUserIsAuditor(user, user); + } - @Test - public void auditsRootEntityCorrectly() throws Exception { + @Test + public void auditsTransitiveEntitiesCorrectly() throws Exception { - assertDatesSet(user); - assertUserIsAuditor(user, user); - } + AuditableRole role = new AuditableRole(); + role.setName("ADMIN"); + user.addRole(role); + repository.save(user); + role = user.getRoles().iterator().next(); - @Test - public void auditsTransitiveEntitiesCorrectly() throws Exception { + assertDatesSet(user); + assertDatesSet(role); + assertUserIsAuditor(user, user); + assertUserIsAuditor(user, role); + } - AuditableRole role = new AuditableRole(); - role.setName("ADMIN"); + private static void assertDatesSet(Auditable auditable) { - user.addRole(role); - repository.save(user); - role = user.getRoles().iterator().next(); + assertThat(auditable.getCreatedDate(), is(notNullValue())); + assertThat(auditable.getLastModifiedDate(), is(notNullValue())); + } - assertDatesSet(user); - assertDatesSet(role); - assertUserIsAuditor(user, user); - assertUserIsAuditor(user, role); - } + private static void assertUserIsAuditor(AuditableUser user, Auditable auditable) { - - private static void assertDatesSet(Auditable auditable) { - - assertThat(auditable.getCreatedDate(), is(notNullValue())); - assertThat(auditable.getLastModifiedDate(), is(notNullValue())); - } - - - private static void assertUserIsAuditor(AuditableUser user, - Auditable auditable) { - - assertThat(auditable.getCreatedBy(), is(user)); - assertThat(auditable.getLastModifiedBy(), is(user)); - } + assertThat(auditable.getCreatedBy(), is(user)); + assertThat(auditable.getLastModifiedBy(), is(user)); + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerUnitTests.java b/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerUnitTests.java index 85b238fa7..44869869e 100644 --- a/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/domain/support/AuditingEntityListenerUnitTests.java @@ -23,7 +23,6 @@ import org.junit.Test; import org.springframework.data.domain.AuditorAware; import org.springframework.data.jpa.domain.sample.AuditableUser; - /** * Unit test for {@code AuditingEntityListener}. * @@ -32,119 +31,109 @@ import org.springframework.data.jpa.domain.sample.AuditableUser; @SuppressWarnings("unchecked") public class AuditingEntityListenerUnitTests { - AuditingEntityListener listener; - AuditorAware auditorAware; + AuditingEntityListener listener; + AuditorAware auditorAware; - AuditableUser user; + AuditableUser user; + @Before + public void setUp() { - @Before - public void setUp() { + listener = new AuditingEntityListener(); + // Explicitly null the AuditorAware as it might have been DI'ed if test + // is run in a test suite with integration tests + // listener.setAuditorAware(null); - listener = new AuditingEntityListener(); - // Explicitly null the AuditorAware as it might have been DI'ed if test - // is run in a test suite with integration tests - // listener.setAuditorAware(null); + user = new AuditableUser(); - user = new AuditableUser(); + auditorAware = mock(AuditorAware.class); + when(auditorAware.getCurrentAuditor()).thenReturn(user); + } - auditorAware = mock(AuditorAware.class); - when(auditorAware.getCurrentAuditor()).thenReturn(user); - } + /** + * Checks that the advice does not set auditor on the target entity if no {@code AuditorAware} was configured. + */ + @Test + public void doesNotSetAuditorIfNotConfigured() { + listener.touchForCreate(user); - /** - * Checks that the advice does not set auditor on the target entity if no - * {@code AuditorAware} was configured. - */ - @Test - public void doesNotSetAuditorIfNotConfigured() { + assertNotNull(user.getCreatedDate()); + assertNotNull(user.getLastModifiedDate()); - listener.touchForCreate(user); + assertNull(user.getCreatedBy()); + assertNull(user.getLastModifiedBy()); + } - assertNotNull(user.getCreatedDate()); - assertNotNull(user.getLastModifiedDate()); + /** + * Checks that the advice sets the auditor on the target entity if an {@code AuditorAware} was configured. + */ + @Test + public void setsAuditorIfConfigured() { - assertNull(user.getCreatedBy()); - assertNull(user.getLastModifiedBy()); - } + listener.setAuditorAware(auditorAware); + listener.touchForCreate(user); - /** - * Checks that the advice sets the auditor on the target entity if an - * {@code AuditorAware} was configured. - */ - @Test - public void setsAuditorIfConfigured() { + assertNotNull(user.getCreatedDate()); + assertNotNull(user.getLastModifiedDate()); - listener.setAuditorAware(auditorAware); + assertNotNull(user.getCreatedBy()); + assertNotNull(user.getLastModifiedBy()); - listener.touchForCreate(user); + verify(auditorAware).getCurrentAuditor(); + } - assertNotNull(user.getCreatedDate()); - assertNotNull(user.getLastModifiedDate()); + /** + * Checks that the advice does not set modification information on creation if the falg is set to {@code false}. + */ + @Test + public void honoursModifiedOnCreationFlag() { - assertNotNull(user.getCreatedBy()); - assertNotNull(user.getLastModifiedBy()); + listener.setAuditorAware(auditorAware); + listener.setModifyOnCreation(false); + listener.touchForCreate(user); - verify(auditorAware).getCurrentAuditor(); - } + assertNotNull(user.getCreatedDate()); + assertNotNull(user.getCreatedBy()); + assertNull(user.getLastModifiedBy()); + assertNull(user.getLastModifiedDate()); - /** - * Checks that the advice does not set modification information on creation - * if the falg is set to {@code false}. - */ - @Test - public void honoursModifiedOnCreationFlag() { + verify(auditorAware).getCurrentAuditor(); + } - listener.setAuditorAware(auditorAware); - listener.setModifyOnCreation(false); - listener.touchForCreate(user); + /** + * Tests that the advice only sets modification data if a not-new entity is handled. + */ + @Test + public void onlySetsModificationDataOnNotNewEntities() { - assertNotNull(user.getCreatedDate()); - assertNotNull(user.getCreatedBy()); + user = new AuditableUser(1L); - assertNull(user.getLastModifiedBy()); - assertNull(user.getLastModifiedDate()); + listener.setAuditorAware(auditorAware); + listener.touchForUpdate(user); - verify(auditorAware).getCurrentAuditor(); - } + assertNull(user.getCreatedBy()); + assertNull(user.getCreatedDate()); + assertNotNull(user.getLastModifiedBy()); + assertNotNull(user.getLastModifiedDate()); - /** - * Tests that the advice only sets modification data if a not-new entity is - * handled. - */ - @Test - public void onlySetsModificationDataOnNotNewEntities() { + verify(auditorAware).getCurrentAuditor(); + } - user = new AuditableUser(1L); + @Test + public void doesNotSetTimeIfConfigured() throws Exception { - listener.setAuditorAware(auditorAware); - listener.touchForUpdate(user); + listener.setDateTimeForNow(false); + listener.setAuditorAware(auditorAware); + listener.touchForCreate(user); - assertNull(user.getCreatedBy()); - assertNull(user.getCreatedDate()); + assertNotNull(user.getCreatedBy()); + assertNull(user.getCreatedDate()); - assertNotNull(user.getLastModifiedBy()); - assertNotNull(user.getLastModifiedDate()); - - verify(auditorAware).getCurrentAuditor(); - } - - - @Test - public void doesNotSetTimeIfConfigured() throws Exception { - - listener.setDateTimeForNow(false); - listener.setAuditorAware(auditorAware); - listener.touchForCreate(user); - - assertNotNull(user.getCreatedBy()); - assertNull(user.getCreatedDate()); - - assertNotNull(user.getLastModifiedBy()); - assertNull(user.getLastModifiedDate()); - } + assertNotNull(user.getLastModifiedBy()); + assertNull(user.getLastModifiedDate()); + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/support/AuditingNamespaceUnitTests.java b/src/test/java/org/springframework/data/jpa/domain/support/AuditingNamespaceUnitTests.java index 7c72802e9..3bebd5ea1 100644 --- a/src/test/java/org/springframework/data/jpa/domain/support/AuditingNamespaceUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/domain/support/AuditingNamespaceUnitTests.java @@ -22,36 +22,30 @@ import org.junit.Test; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; - /** * Unit test for the JPA {@code auditing} namespace element. * * @author Oliver Gierke */ -public class AuditingNamespaceUnitTests extends - AuditingBeanFactoryPostProcessorUnitTests { +public class AuditingNamespaceUnitTests extends AuditingBeanFactoryPostProcessorUnitTests { - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.domain.support. - * AuditingBeanFactoryPostProcessorUnitTests#getConfigFile() - */ - @Override - protected String getConfigFile() { + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.domain.support. + * AuditingBeanFactoryPostProcessorUnitTests#getConfigFile() + */ + @Override + protected String getConfigFile() { - return "auditing-namespace-context.xml"; - } + return "auditing-namespace-context.xml"; + } + @Test + public void registersBeanDefinitions() throws Exception { - @Test - public void registersBeanDefinitions() throws Exception { - - BeanDefinition definition = - beanFactory.getBeanDefinition(AuditingEntityListener.class - .getName()); - PropertyValue propertyValue = - definition.getPropertyValues().getPropertyValue("auditorAware"); - assertThat(propertyValue, is(notNullValue())); - } + BeanDefinition definition = beanFactory.getBeanDefinition(AuditingEntityListener.class.getName()); + PropertyValue propertyValue = definition.getPropertyValues().getPropertyValue("auditorAware"); + assertThat(propertyValue, is(notNullValue())); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/EclipseLinkNamespaceUserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/EclipseLinkNamespaceUserRepositoryTests.java index 1e4549e05..fb22096a5 100644 --- a/src/test/java/org/springframework/data/jpa/repository/EclipseLinkNamespaceUserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/EclipseLinkNamespaceUserRepositoryTests.java @@ -19,16 +19,13 @@ import org.springframework.data.jpa.repository.sample.UserRepository; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; - /** - * Testcase to run {@link UserRepository} integration tests on top of - * EclipseLink. + * Testcase to run {@link UserRepository} integration tests on top of EclipseLink. * * @author Oliver Gierke */ @DirtiesContext @ContextConfiguration(value = "classpath:eclipselink.xml", inheritLocations = true) -public class EclipseLinkNamespaceUserRepositoryTests extends - NamespaceUserRepositoryTests { +public class EclipseLinkNamespaceUserRepositoryTests extends NamespaceUserRepositoryTests { } diff --git a/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java b/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java index 86577e6dd..69711dba2 100644 --- a/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/EclipseLinkUserRepositoryFinderTests.java @@ -19,7 +19,6 @@ import org.junit.Ignore; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; - /** * Ignores some test cases using IN queries as long as we wait for fix for * https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477. @@ -29,6 +28,5 @@ import org.springframework.test.context.ContextConfiguration; @Ignore @DirtiesContext @ContextConfiguration(value = "classpath:eclipselink.xml", inheritLocations = true) -public class EclipseLinkUserRepositoryFinderTests extends - UserRepositoryFinderTests { +public class EclipseLinkUserRepositoryFinderTests extends UserRepositoryFinderTests { } diff --git a/src/test/java/org/springframework/data/jpa/repository/NamespaceUserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/NamespaceUserRepositoryTests.java index 904ac536f..efc05733d 100644 --- a/src/test/java/org/springframework/data/jpa/repository/NamespaceUserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/NamespaceUserRepositoryTests.java @@ -26,10 +26,8 @@ import org.springframework.dao.annotation.PersistenceExceptionTranslationPostPro import org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor; import org.springframework.test.context.ContextConfiguration; - /** - * Use namespace context to run tests. Checks for existence of required - * PostProcessors, too. + * Use namespace context to run tests. Checks for existence of required PostProcessors, too. * * @author Oliver Gierke * @author Eberhard Wolff @@ -37,21 +35,19 @@ import org.springframework.test.context.ContextConfiguration; @ContextConfiguration(locations = "classpath:config/namespace-application-context.xml", inheritLocations = false) public class NamespaceUserRepositoryTests extends UserRepositoryTests { - @Autowired - ListableBeanFactory beanFactory; + @Autowired + ListableBeanFactory beanFactory; + @Test + public void registersPostProcessors() { - @Test - public void registersPostProcessors() { + hasAtLeastOneBeanOfType(PersistenceAnnotationBeanPostProcessor.class); + hasAtLeastOneBeanOfType(PersistenceExceptionTranslationPostProcessor.class); + } - hasAtLeastOneBeanOfType(PersistenceAnnotationBeanPostProcessor.class); - hasAtLeastOneBeanOfType(PersistenceExceptionTranslationPostProcessor.class); - } + private void hasAtLeastOneBeanOfType(Class beanType) { - - private void hasAtLeastOneBeanOfType(Class beanType) { - - Map beans = beanFactory.getBeansOfType(beanType); - assertFalse(beans.entrySet().isEmpty()); - } + Map beans = beanFactory.getBeansOfType(beanType); + assertFalse(beans.entrySet().isEmpty()); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/ORMInfrastructureTests.java b/src/test/java/org/springframework/data/jpa/repository/ORMInfrastructureTests.java index bf0e062ac..c7b168b41 100644 --- a/src/test/java/org/springframework/data/jpa/repository/ORMInfrastructureTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/ORMInfrastructureTests.java @@ -24,10 +24,8 @@ import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - /** - * Simple test case launching an {@code ApplicationContext} to test - * infrastructure configuration. + * Simple test case launching an {@code ApplicationContext} to test infrastructure configuration. * * @author Oliver Gierke */ @@ -35,18 +33,17 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ContextConfiguration(locations = "classpath:infrastructure.xml") public class ORMInfrastructureTests { - @Autowired - ApplicationContext context; + @Autowired + ApplicationContext context; + /** + * Tests, that the context got initialized and injected correctly. + * + * @throws Exception + */ + @Test + public void contextInitialized() throws Exception { - /** - * Tests, that the context got initialized and injected correctly. - * - * @throws Exception - */ - @Test - public void contextInitialized() throws Exception { - - assertNotNull(context); - } + assertNotNull(context); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/OpenJpaNamespaceUserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/OpenJpaNamespaceUserRepositoryTests.java index 213d10cd6..fc249b810 100644 --- a/src/test/java/org/springframework/data/jpa/repository/OpenJpaNamespaceUserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/OpenJpaNamespaceUserRepositoryTests.java @@ -18,14 +18,12 @@ package org.springframework.data.jpa.repository; import org.springframework.data.jpa.repository.sample.UserRepository; import org.springframework.test.context.ContextConfiguration; - /** * Testcase to run {@link UserRepository} integration tests on top of OpenJPA. * * @author Oliver Gierke */ @ContextConfiguration(value = "classpath:openjpa.xml", inheritLocations = true) -public class OpenJpaNamespaceUserRepositoryTests extends - NamespaceUserRepositoryTests { +public class OpenJpaNamespaceUserRepositoryTests extends NamespaceUserRepositoryTests { } \ No newline at end of file diff --git a/src/test/java/org/springframework/data/jpa/repository/RoleRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/RoleRepositoryIntegrationTests.java index 0ff2fea60..8970d9a1d 100644 --- a/src/test/java/org/springframework/data/jpa/repository/RoleRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/RoleRepositoryIntegrationTests.java @@ -28,7 +28,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.transaction.annotation.Transactional; - /** * Integration tests for {@link RoleRepository}. * @@ -39,30 +38,28 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class RoleRepositoryIntegrationTests { - @Autowired - RoleRepository repository; + @Autowired + RoleRepository repository; + @Test + public void createsRole() throws Exception { - @Test - public void createsRole() throws Exception { + Role reference = new Role("ADMIN"); + Role result = repository.save(reference); + assertThat(result, is(reference)); + } - Role reference = new Role("ADMIN"); - Role result = repository.save(reference); - assertThat(result, is(reference)); - } + @Test + public void updatesRole() throws Exception { + Role reference = new Role("ADMIN"); + Role result = repository.save(reference); + assertThat(result, is(reference)); - @Test - public void updatesRole() throws Exception { + // Change role name + ReflectionTestUtils.setField(reference, "name", "USER"); + repository.save(reference); - Role reference = new Role("ADMIN"); - Role result = repository.save(reference); - assertThat(result, is(reference)); - - // Change role name - ReflectionTestUtils.setField(reference, "name", "USER"); - repository.save(reference); - - assertThat(repository.findOne(result.getId()), is(reference)); - } + assertThat(repository.findOne(result.getId()), is(reference)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/SimpleJpaParameterBindingTests.java b/src/test/java/org/springframework/data/jpa/repository/SimpleJpaParameterBindingTests.java index dd96ce301..43600e9c6 100644 --- a/src/test/java/org/springframework/data/jpa/repository/SimpleJpaParameterBindingTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/SimpleJpaParameterBindingTests.java @@ -38,7 +38,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; - /** * @author Oliver Gierke */ @@ -50,56 +49,52 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class SimpleJpaParameterBindingTests { - @PersistenceContext - EntityManager em; + @PersistenceContext + EntityManager em; + @Test + @Ignore + public void bindArray() { - @Test - @Ignore - public void bindArray() { + User user = new User("Dave", "Matthews", "foo@bar.de"); + em.persist(user); + em.flush(); - User user = new User("Dave", "Matthews", "foo@bar.de"); - em.persist(user); - em.flush(); + CriteriaBuilder builder = em.getCriteriaBuilder(); - CriteriaBuilder builder = em.getCriteriaBuilder(); + CriteriaQuery criteria = builder.createQuery(User.class); + Root root = criteria.from(User.class); + ParameterExpression parameter = builder.parameter(String[].class); + criteria.where(root.get("firstname").in(parameter)); - CriteriaQuery criteria = builder.createQuery(User.class); - Root root = criteria.from(User.class); - ParameterExpression parameter = - builder.parameter(String[].class); - criteria.where(root.get("firstname").in(parameter)); + TypedQuery query = em.createQuery(criteria); + query.setParameter(parameter, new String[] { "Dave", "Carter" }); - TypedQuery query = em.createQuery(criteria); - query.setParameter(parameter, new String[] { "Dave", "Carter" }); + List result = query.getResultList(); + assertThat(result.isEmpty(), is(false)); + } - List result = query.getResultList(); - assertThat(result.isEmpty(), is(false)); - } + @Test + @SuppressWarnings("rawtypes") + public void bindCollection() { + User user = new User("Dave", "Matthews", "foo@bar.de"); + em.persist(user); + em.flush(); - @Test - @SuppressWarnings("rawtypes") - public void bindCollection() { + CriteriaBuilder builder = em.getCriteriaBuilder(); - User user = new User("Dave", "Matthews", "foo@bar.de"); - em.persist(user); - em.flush(); + CriteriaQuery criteria = builder.createQuery(User.class); + Root root = criteria.from(User.class); + ParameterExpression parameter = builder.parameter(Collection.class); + criteria.where(root.get("firstname").in(parameter)); - CriteriaBuilder builder = em.getCriteriaBuilder(); + TypedQuery query = em.createQuery(criteria); - CriteriaQuery criteria = builder.createQuery(User.class); - Root root = criteria.from(User.class); - ParameterExpression parameter = - builder.parameter(Collection.class); - criteria.where(root.get("firstname").in(parameter)); + query.setParameter(parameter, Arrays.asList("Dave")); - TypedQuery query = em.createQuery(criteria); - - query.setParameter(parameter, Arrays.asList("Dave")); - - List result = query.getResultList(); - assertThat(result.isEmpty(), is(false)); - assertThat(result.get(0), is(user)); - } + List result = query.getResultList(); + assertThat(result.isEmpty(), is(false)); + assertThat(result.get(0), is(user)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java index 532da5bb6..ca6206497 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java @@ -36,10 +36,8 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; - /** - * Integration test for executing finders, thus testing various query lookup - * strategies. + * Integration test for executing finders, thus testing various query lookup strategies. * * @see QueryLookupStrategy * @author Oliver Gierke @@ -49,134 +47,108 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class UserRepositoryFinderTests { - @Autowired - UserRepository userRepository; + @Autowired + UserRepository userRepository; - User dave, carter, oliver; + User dave, carter, oliver; + @Before + public void setUp() { - @Before - public void setUp() { + // This one matches both criterias + dave = new User("Dave", "Matthews", "dave@dmband.com"); + userRepository.save(dave); - // This one matches both criterias - dave = new User("Dave", "Matthews", "dave@dmband.com"); - userRepository.save(dave); + // This one matches only the second one + carter = new User("Carter", "Beauford", "carter@dmband.com"); + userRepository.save(carter); - // This one matches only the second one - carter = new User("Carter", "Beauford", "carter@dmband.com"); - userRepository.save(carter); + oliver = new User("Oliver August", "Matthews", "oliver@dmband.com"); + userRepository.save(oliver); + } - oliver = new User("Oliver August", "Matthews", "oliver@dmband.com"); - userRepository.save(oliver); - } + /** + * Tests creation of a simple query. + */ + @Test + public void testSimpleCustomCreatedFinder() { + User user = userRepository.findByEmailAddressAndLastname("dave@dmband.com", "Matthews"); + assertEquals(dave, user); + } - /** - * Tests creation of a simple query. - */ - @Test - public void testSimpleCustomCreatedFinder() { + /** + * Tests that the repository returns {@code null} for not found objects for finder methods that return a single domain + * object. + */ + @Test + public void returnsNullIfNothingFound() { - User user = - userRepository.findByEmailAddressAndLastname("dave@dmband.com", - "Matthews"); - assertEquals(dave, user); - } + User user = userRepository.findByEmailAddress("foobar"); + assertEquals(null, user); + } + /** + * Tests creation of a simple query consisting of {@code AND} and {@code OR} parts. + */ + @Test + public void testAndOrFinder() { - /** - * Tests that the repository returns {@code null} for not found objects for - * finder methods that return a single domain object. - */ - @Test - public void returnsNullIfNothingFound() { + List users = userRepository.findByEmailAddressAndLastnameOrFirstname("dave@dmband.com", "Matthews", "Carter"); - User user = userRepository.findByEmailAddress("foobar"); - assertEquals(null, user); - } + assertNotNull(users); + assertEquals(2, users.size()); + assertTrue(users.contains(dave)); + assertTrue(users.contains(carter)); + } + @Test + public void executesPagingMethodToPageCorrectly() { - /** - * Tests creation of a simple query consisting of {@code AND} and {@code OR} - * parts. - */ - @Test - public void testAndOrFinder() { + Page page = userRepository.findByLastname(new PageRequest(0, 1), "Matthews"); + assertThat(page.getNumberOfElements(), is(1)); + assertThat(page.getTotalElements(), is(2L)); + assertThat(page.getTotalPages(), is(2)); + } - List users = - userRepository.findByEmailAddressAndLastnameOrFirstname( - "dave@dmband.com", "Matthews", "Carter"); + @Test + public void executesPagingMethodToListCorrectly() { - assertNotNull(users); - assertEquals(2, users.size()); - assertTrue(users.contains(dave)); - assertTrue(users.contains(carter)); - } + List list = userRepository.findByFirstname("Carter", new PageRequest(0, 1)); + assertThat(list.size(), is(1)); + } + @Test + public void executesInKeywordForPageCorrectly() { - @Test - public void executesPagingMethodToPageCorrectly() { + Page page = userRepository.findByFirstnameIn(new PageRequest(0, 1), "Dave", "Oliver August"); - Page page = - userRepository - .findByLastname(new PageRequest(0, 1), "Matthews"); - assertThat(page.getNumberOfElements(), is(1)); - assertThat(page.getTotalElements(), is(2L)); - assertThat(page.getTotalPages(), is(2)); - } + assertThat(page.getNumberOfElements(), is(1)); + assertThat(page.getTotalElements(), is(2L)); + assertThat(page.getTotalPages(), is(2)); + } + @Test + public void executesNotInQueryCorrectly() throws Exception { - @Test - public void executesPagingMethodToListCorrectly() { + List result = userRepository.findByFirstnameNotIn(Arrays.asList("Dave", "Carter")); + assertThat(result.size(), is(1)); + assertThat(result.get(0), is(oliver)); + } - List list = - userRepository.findByFirstname("Carter", new PageRequest(0, 1)); - assertThat(list.size(), is(1)); - } + @Test + public void respectsPageableOrderOnQueryGenerateFromMethodName() throws Exception { - - @Test - public void executesInKeywordForPageCorrectly() { - - Page page = - userRepository.findByFirstnameIn(new PageRequest(0, 1), "Dave", - "Oliver August"); - - assertThat(page.getNumberOfElements(), is(1)); - assertThat(page.getTotalElements(), is(2L)); - assertThat(page.getTotalPages(), is(2)); - } - - - @Test - public void executesNotInQueryCorrectly() throws Exception { - - List result = - userRepository.findByFirstnameNotIn(Arrays.asList("Dave", - "Carter")); - assertThat(result.size(), is(1)); - assertThat(result.get(0), is(oliver)); - } - - - @Test - public void respectsPageableOrderOnQueryGenerateFromMethodName() - throws Exception { - - Page ascending = - userRepository.findByLastnameLike(new PageRequest(0, 10, - new Sort(Direction.ASC, "firstname")), "Matthews"); - Page descending = - userRepository.findByLastnameLike(new PageRequest(0, 10, - new Sort(Direction.DESC, "firstname")), "Matthews"); - assertThat(ascending.getTotalElements(), is(2L)); - assertThat(descending.getTotalElements(), is(2L)); - assertThat(ascending.getContent().get(0).getFirstname(), - is(not(equalTo(descending.getContent().get(0).getFirstname())))); - assertThat(ascending.getContent().get(0).getFirstname(), - is(equalTo(descending.getContent().get(1).getFirstname()))); - assertThat(ascending.getContent().get(1).getFirstname(), - is(equalTo(descending.getContent().get(0).getFirstname()))); - } + Page ascending = userRepository.findByLastnameLike(new PageRequest(0, 10, + new Sort(Direction.ASC, "firstname")), "Matthews"); + Page descending = userRepository.findByLastnameLike(new PageRequest(0, 10, new Sort(Direction.DESC, + "firstname")), "Matthews"); + assertThat(ascending.getTotalElements(), is(2L)); + assertThat(descending.getTotalElements(), is(2L)); + assertThat(ascending.getContent().get(0).getFirstname(), is(not(equalTo(descending.getContent().get(0) + .getFirstname())))); + assertThat(ascending.getContent().get(0).getFirstname(), is(equalTo(descending.getContent().get(1).getFirstname()))); + assertThat(ascending.getContent().get(1).getFirstname(), is(equalTo(descending.getContent().get(0).getFirstname()))); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java index 71a2ff66c..af579d7f9 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -52,14 +52,11 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; - /** - * Base integration test class for {@code UserRepository}. Loads a basic - * (non-namespace) Spring configuration file as well as Hibernate configuration - * to execute tests. + * Base integration test class for {@code UserRepository}. Loads a basic (non-namespace) Spring configuration file as + * well as Hibernate configuration to execute tests. *

- * To test further persistence providers subclass this class and provide a - * custom provider configuration. + * To test further persistence providers subclass this class and provide a custom provider configuration. * * @author Oliver Gierke */ @@ -68,771 +65,674 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class UserRepositoryTests { - @PersistenceContext - EntityManager em; + @PersistenceContext + EntityManager em; - // CUT - @Autowired - UserRepository repository; + // CUT + @Autowired + UserRepository repository; - // Test fixture - User firstUser, secondUser, thirdUser; - Integer id; + // Test fixture + User firstUser, secondUser, thirdUser; + Integer id; + @Before + public void setUp() { - @Before - public void setUp() { + firstUser = new User("Oliver", "Gierke", "gierke@synyx.de"); + secondUser = new User("Joachim", "Arrasz", "arrasz@synyx.de"); + thirdUser = new User("Dave", "Matthews", "no@email.com"); + } - firstUser = new User("Oliver", "Gierke", "gierke@synyx.de"); - secondUser = new User("Joachim", "Arrasz", "arrasz@synyx.de"); - thirdUser = new User("Dave", "Matthews", "no@email.com"); - } + /** + * Tests creation of users. + */ + @Test + public void testCreation() { + Query countQuery = em.createQuery("select count(u) from User u"); + Long before = (Long) countQuery.getSingleResult(); - /** - * Tests creation of users. - */ - @Test - public void testCreation() { + flushTestUsers(); - Query countQuery = em.createQuery("select count(u) from User u"); - Long before = (Long) countQuery.getSingleResult(); + assertEquals(before + 3, countQuery.getSingleResult()); + } - flushTestUsers(); + /** + * Tests reading a single user. + * + * @throws Exception + */ + @Test + public void testRead() throws Exception { - assertEquals(before + 3, countQuery.getSingleResult()); - } + flushTestUsers(); + User foundPerson = repository.findOne(id); + assertEquals(firstUser.getFirstname(), foundPerson.getFirstname()); + } - /** - * Tests reading a single user. - * - * @throws Exception - */ - @Test - public void testRead() throws Exception { + /** + * Asserts, that a call to {@code UserRepository#readId(Integer)} returns {@code null} for invalid not {@code null} + * ids. + */ + @Test + public void testReadByIdReturnsNullForNotFoundEntities() { - flushTestUsers(); + flushTestUsers(); - User foundPerson = repository.findOne(id); - assertEquals(firstUser.getFirstname(), foundPerson.getFirstname()); - } + assertNull(repository.findOne(id * 27)); + } + @Test + public void savesCollectionCorrectly() throws Exception { - /** - * Asserts, that a call to {@code UserRepository#readId(Integer)} returns - * {@code null} for invalid not {@code null} ids. - */ - @Test - public void testReadByIdReturnsNullForNotFoundEntities() { + List result = repository.save(Arrays.asList(firstUser, secondUser, thirdUser)); + assertNotNull(result); + assertThat(result.size(), is(3)); + assertThat(result, hasItems(firstUser, secondUser, thirdUser)); + } - flushTestUsers(); + @Test + public void savingNullCollectionIsNoOp() throws Exception { - assertNull(repository.findOne(id * 27)); - } + List result = repository.save((Collection) null); + assertNotNull(result); + assertTrue(result.isEmpty()); + } + @Test + public void savingEmptyCollectionIsNoOp() throws Exception { - @Test - public void savesCollectionCorrectly() throws Exception { + List result = repository.save(new ArrayList()); + assertNotNull(result); + assertTrue(result.isEmpty()); + } - List result = - repository - .save(Arrays.asList(firstUser, secondUser, thirdUser)); - assertNotNull(result); - assertThat(result.size(), is(3)); - assertThat(result, hasItems(firstUser, secondUser, thirdUser)); - } + /** + * Tests updating a user. + */ + @Test + public void testUpdate() { + flushTestUsers(); - @Test - public void savingNullCollectionIsNoOp() throws Exception { + User foundPerson = repository.findOne(id); + foundPerson.setLastname("Schlicht"); - List result = repository.save((Collection) null); - assertNotNull(result); - assertTrue(result.isEmpty()); - } + User updatedPerson = repository.findOne(id); + assertEquals(foundPerson.getFirstname(), updatedPerson.getFirstname()); + } + @Test + public void existReturnsWhetherAnEntityCanBeLoaded() throws Exception { - @Test - public void savingEmptyCollectionIsNoOp() throws Exception { + flushTestUsers(); + assertTrue(repository.exists(id)); + assertFalse(repository.exists(id * 27)); + } - List result = repository.save(new ArrayList()); - assertNotNull(result); - assertTrue(result.isEmpty()); - } + @Test + public void deletesAUserById() { + flushTestUsers(); - /** - * Tests updating a user. - */ - @Test - public void testUpdate() { + repository.delete(firstUser.getId()); + assertNull(repository.findOne(firstUser.getId())); + } - flushTestUsers(); + /** + * Tests deleting a user. + */ + @Test + public void testDelete() { - User foundPerson = repository.findOne(id); - foundPerson.setLastname("Schlicht"); + flushTestUsers(); - User updatedPerson = repository.findOne(id); - assertEquals(foundPerson.getFirstname(), updatedPerson.getFirstname()); - } + repository.delete(firstUser); + assertNull(repository.findOne(id)); + } + @Test + public void returnsAllSortedCorrectly() throws Exception { - @Test - public void existReturnsWhetherAnEntityCanBeLoaded() throws Exception { + flushTestUsers(); + List result = repository.findAll(new Sort(ASC, "lastname")); + assertNotNull(result); + assertThat(result.size(), is(3)); + assertThat(result.get(0), is(secondUser)); + assertThat(result.get(1), is(firstUser)); + assertThat(result.get(2), is(thirdUser)); + } - flushTestUsers(); - assertTrue(repository.exists(id)); - assertFalse(repository.exists(id * 27)); - } + @Test + public void deleteColletionOfEntities() { + flushTestUsers(); - @Test - public void deletesAUserById() { + long before = repository.count(); - flushTestUsers(); + repository.delete(Arrays.asList(firstUser, secondUser)); + assertThat(repository.count(), is(before - 2)); + } - repository.delete(firstUser.getId()); - assertNull(repository.findOne(firstUser.getId())); - } + @Test + public void batchDeleteColletionOfEntities() { + flushTestUsers(); - /** - * Tests deleting a user. - */ - @Test - public void testDelete() { + long before = repository.count(); - flushTestUsers(); + repository.deleteInBatch(Arrays.asList(firstUser, secondUser)); + assertThat(repository.count(), is(before - 2)); + } - repository.delete(firstUser); - assertNull(repository.findOne(id)); - } + @Test + public void deleteEmptyCollectionDoesNotDeleteAnything() { + assertDeleteCallDoesNotDeleteAnything(new ArrayList()); + } - @Test - public void returnsAllSortedCorrectly() throws Exception { + @Test + public void deleteWithNullDoesNotDeleteAnything() throws Exception { - flushTestUsers(); - List result = repository.findAll(new Sort(ASC, "lastname")); - assertNotNull(result); - assertThat(result.size(), is(3)); - assertThat(result.get(0), is(secondUser)); - assertThat(result.get(1), is(firstUser)); - assertThat(result.get(2), is(thirdUser)); - } + assertDeleteCallDoesNotDeleteAnything(null); + } + private void assertDeleteCallDoesNotDeleteAnything(List collection) { - @Test - public void deleteColletionOfEntities() { + flushTestUsers(); + long count = repository.count(); - flushTestUsers(); + repository.delete(collection); + assertEquals(count, repository.count()); + } - long before = repository.count(); + @Test + public void executesManipulatingQuery() throws Exception { - repository.delete(Arrays.asList(firstUser, secondUser)); - assertThat(repository.count(), is(before - 2)); - } + flushTestUsers(); + repository.renameAllUsersTo("newLastname"); + long expected = repository.count(); + assertThat(repository.findByLastname("newLastname").size(), is(Long.valueOf(expected).intValue())); + } - @Test - public void batchDeleteColletionOfEntities() { + /** + * Make sure no {@link NullPointerException} is being thrown. + * + * @see Ticket #110 + */ + @Test + public void testFinderInvocationWithNullParameter() { - flushTestUsers(); + flushTestUsers(); - long before = repository.count(); + repository.findByLastname(null); + } - repository.deleteInBatch(Arrays.asList(firstUser, secondUser)); - assertThat(repository.count(), is(before - 2)); - } + /** + * Tests, that searching by the lastname of the reference user returns exactly that instance. + * + * @throws Exception + */ + @Test + public void testFindByLastname() throws Exception { + flushTestUsers(); - @Test - public void deleteEmptyCollectionDoesNotDeleteAnything() { + List byName = repository.findByLastname("Gierke"); - assertDeleteCallDoesNotDeleteAnything(new ArrayList()); - } + assertTrue(byName.size() == 1); + assertEquals(firstUser, byName.get(0)); + } + /** + * Tests, that searching by the email address of the reference user returns exactly that instance. + * + * @throws Exception + */ + @Test + public void testFindByEmailAddress() throws Exception { - @Test - public void deleteWithNullDoesNotDeleteAnything() throws Exception { + flushTestUsers(); - assertDeleteCallDoesNotDeleteAnything(null); - } + User byName = repository.findByEmailAddress("gierke@synyx.de"); + assertNotNull(byName); + assertEquals(firstUser, byName); + } - private void assertDeleteCallDoesNotDeleteAnything(List collection) { + /** + * Tests reading all users. + */ + @Test + public void testReadAll() { - flushTestUsers(); - long count = repository.count(); + flushTestUsers(); - repository.delete(collection); - assertEquals(count, repository.count()); - } + List reference = Arrays.asList(firstUser, secondUser); + assertTrue(repository.findAll().containsAll(reference)); + } + /** + * Tests that all users get deleted by triggering {@link UserRepository#deleteAll()}. + * + * @throws Exception + */ + @Test + public void deleteAll() throws Exception { - @Test - public void executesManipulatingQuery() throws Exception { + flushTestUsers(); - flushTestUsers(); - repository.renameAllUsersTo("newLastname"); + repository.deleteAll(); - long expected = repository.count(); - assertThat(repository.findByLastname("newLastname").size(), is(Long - .valueOf(expected).intValue())); - } + assertEquals(0L, repository.count()); + } + /** + * Tests cascading persistence. + */ + @Test + public void testCascadesPersisting() { - /** - * Make sure no {@link NullPointerException} is being thrown. - * - * @see Ticket #110 - */ - @Test - public void testFinderInvocationWithNullParameter() { + // Create link prior to persisting + firstUser.addColleague(secondUser); - flushTestUsers(); + // Persist + flushTestUsers(); - repository.findByLastname(null); - } + // Fetches first user from database + User firstReferenceUser = repository.findOne(firstUser.getId()); + assertEquals(firstUser, firstReferenceUser); + // Fetch colleagues and assert link + Set colleagues = firstReferenceUser.getColleagues(); + assertEquals(1, colleagues.size()); + assertTrue(colleagues.contains(secondUser)); + } - /** - * Tests, that searching by the lastname of the reference user returns - * exactly that instance. - * - * @throws Exception - */ - @Test - public void testFindByLastname() throws Exception { + /** + * Tests, that persisting a relationsship without cascade attributes throws a {@code DataAccessException}. + */ + @Test(expected = DataAccessException.class) + public void testPreventsCascadingRolePersisting() { - flushTestUsers(); + firstUser.addRole(new Role("USER")); - List byName = repository.findByLastname("Gierke"); + flushTestUsers(); + } - assertTrue(byName.size() == 1); - assertEquals(firstUser, byName.get(0)); - } + /** + * Tests cascading on {@literal merge} operation. + */ + @Test + public void testMergingCascadesCollegueas() { + firstUser.addColleague(secondUser); + flushTestUsers(); - /** - * Tests, that searching by the email address of the reference user returns - * exactly that instance. - * - * @throws Exception - */ - @Test - public void testFindByEmailAddress() throws Exception { + firstUser.addColleague(new User("Florian", "Hopf", "hopf@synyx.de")); + firstUser = repository.save(firstUser); - flushTestUsers(); + User reference = repository.findOne(firstUser.getId()); + Set colleagues = reference.getColleagues(); - User byName = repository.findByEmailAddress("gierke@synyx.de"); + assertNotNull(colleagues); + assertEquals(2, colleagues.size()); + } - assertNotNull(byName); - assertEquals(firstUser, byName); - } + /** + * Tests, that the generic repository implements count correctly. + */ + @Test + public void testCountsCorrectly() { + long count = repository.count(); - /** - * Tests reading all users. - */ - @Test - public void testReadAll() { + User user = new User(); + user.setEmailAddress("gierke@synyx.de"); + repository.save(user); - flushTestUsers(); + assertTrue(repository.count() == count + 1); + } - List reference = Arrays.asList(firstUser, secondUser); - assertTrue(repository.findAll().containsAll(reference)); - } + /** + * Tests invoking a method of a custom implementation of the repository interface. + */ + @Test + public void testInvocationOfCustomImplementation() { + repository.someCustomMethod(new User()); + } - /** - * Tests that all users get deleted by triggering - * {@link UserRepository#deleteAll()}. - * - * @throws Exception - */ - @Test - public void deleteAll() throws Exception { + /** + * Tests that overriding a finder method is recognized by the repository implementation. If an overriding method is + * found it will will be invoked instead of the automatically generated finder. + */ + @Test + public void testOverwritingFinder() { - flushTestUsers(); + repository.findByOverrridingMethod(); + } - repository.deleteAll(); + @Test + public void testUsesQueryAnnotation() { - assertEquals(0L, repository.count()); - } + assertEquals(null, repository.findByAnnotatedQuery("gierke@synyx.de")); + } + @Test + public void testExecutionOfProjectingMethod() { - /** - * Tests cascading persistence. - */ - @Test - public void testCascadesPersisting() { + flushTestUsers(); + assertEquals(1, repository.countWithFirstname("Oliver").longValue()); + } - // Create link prior to persisting - firstUser.addColleague(secondUser); + @Test + public void executesSpecificationCorrectly() { - // Persist - flushTestUsers(); + flushTestUsers(); + assertThat(repository.findAll(where(userHasFirstname("Oliver"))).size(), is(1)); + } - // Fetches first user from database - User firstReferenceUser = repository.findOne(firstUser.getId()); - assertEquals(firstUser, firstReferenceUser); + @Test + public void executesSingleEntitySpecificationCorrectly() throws Exception { - // Fetch colleagues and assert link - Set colleagues = firstReferenceUser.getColleagues(); - assertEquals(1, colleagues.size()); - assertTrue(colleagues.contains(secondUser)); - } + flushTestUsers(); + assertThat(repository.findOne(userHasFirstname("Oliver")), is(firstUser)); + } + @Test + public void returnsNullIfNoEntityFoundForSingleEntitySpecification() throws Exception { - /** - * Tests, that persisting a relationsship without cascade attributes throws - * a {@code DataAccessException}. - */ - @Test(expected = DataAccessException.class) - public void testPreventsCascadingRolePersisting() { + flushTestUsers(); + assertThat(repository.findOne(userHasLastname("Beauford")), is(nullValue())); + } - firstUser.addRole(new Role("USER")); + @Test(expected = IncorrectResultSizeDataAccessException.class) + public void throwsExceptionForUnderSpecifiedSingleEntitySpecification() { - flushTestUsers(); - } + flushTestUsers(); + repository.findOne(userHasFirstnameLike("e")); + } + @Test + public void executesCombinedSpecificationsCorrectly() { - /** - * Tests cascading on {@literal merge} operation. - */ - @Test - public void testMergingCascadesCollegueas() { + flushTestUsers(); + Specification spec = where(userHasFirstname("Oliver")).or(userHasLastname("Arrasz")); + assertThat(repository.findAll(spec).size(), is(2)); + } - firstUser.addColleague(secondUser); - flushTestUsers(); + @Test + public void executesCombinedSpecificationsWithPageableCorrectly() { - firstUser.addColleague(new User("Florian", "Hopf", "hopf@synyx.de")); - firstUser = repository.save(firstUser); + flushTestUsers(); + Specification spec = where(userHasFirstname("Oliver")).or(userHasLastname("Arrasz")); - User reference = repository.findOne(firstUser.getId()); - Set colleagues = reference.getColleagues(); + Page users = repository.findAll(spec, new PageRequest(0, 1)); + assertThat(users.getSize(), is(1)); + assertThat(users.hasPreviousPage(), is(false)); + assertThat(users.getTotalElements(), is(2L)); + } - assertNotNull(colleagues); - assertEquals(2, colleagues.size()); - } + /** + * Flushes test users to the database. + */ + private void flushTestUsers() { + firstUser = repository.save(firstUser); + secondUser = repository.save(secondUser); + thirdUser = repository.save(thirdUser); - /** - * Tests, that the generic repository implements count correctly. - */ - @Test - public void testCountsCorrectly() { + repository.flush(); - long count = repository.count(); + id = firstUser.getId(); - User user = new User(); - user.setEmailAddress("gierke@synyx.de"); - repository.save(user); + assertThat(id, is(notNullValue())); + assertThat(secondUser.getId(), is(notNullValue())); + assertThat(thirdUser.getId(), is(notNullValue())); - assertTrue(repository.count() == count + 1); - } + assertThat(repository.exists(id), is(true)); + assertThat(repository.exists(secondUser.getId()), is(true)); + assertThat(repository.exists(thirdUser.getId()), is(true)); + } + @Test + public void executesMethodWithAnnotatedNamedParametersCorrectly() throws Exception { - /** - * Tests invoking a method of a custom implementation of the repository - * interface. - */ - @Test - public void testInvocationOfCustomImplementation() { + firstUser = repository.save(firstUser); + secondUser = repository.save(secondUser); - repository.someCustomMethod(new User()); - } + assertTrue(repository.findByLastnameOrFirstname("Oliver", "Arrasz").containsAll( + Arrays.asList(firstUser, secondUser))); + } + @Test + @Ignore + public void executesMethodWithNamedParametersCorrectly() throws Exception { - /** - * Tests that overriding a finder method is recognized by the repository - * implementation. If an overriding method is found it will will be invoked - * instead of the automatically generated finder. - */ - @Test - public void testOverwritingFinder() { + firstUser = repository.save(firstUser); + secondUser = repository.save(secondUser); - repository.findByOverrridingMethod(); - } + assertThat(repository.findByLastnameOrFirstnameUnannotated("Oliver", "Arrasz"), hasItems(firstUser, secondUser)); + } + @Test + public void executesMethodWithNamedParametersCorrectlyOnMethodsWithQueryCreation() throws Exception { - @Test - public void testUsesQueryAnnotation() { + firstUser = repository.save(firstUser); + secondUser = repository.save(secondUser); - assertEquals(null, repository.findByAnnotatedQuery("gierke@synyx.de")); - } + List result = repository.findByFirstnameOrLastname("Oliver", "Arrasz"); + assertThat(result.size(), is(2)); + assertThat(result, hasItems(firstUser, secondUser)); + } + @Test + public void executesLikeAndOrderByCorrectly() throws Exception { - @Test - public void testExecutionOfProjectingMethod() { + flushTestUsers(); - flushTestUsers(); - assertEquals(1, repository.countWithFirstname("Oliver").longValue()); - } + List result = repository.findByLastnameLikeOrderByFirstnameDesc("%r%"); + assertThat(result.size(), is(2)); + assertEquals(firstUser, result.get(0)); + assertEquals(secondUser, result.get(1)); + } + @Test + public void executesNotLikeCorrectly() throws Exception { - @Test - public void executesSpecificationCorrectly() { + flushTestUsers(); - flushTestUsers(); - assertThat( - repository.findAll(where(userHasFirstname("Oliver"))).size(), - is(1)); - } + List result = repository.findByLastnameNotLike("%er%"); + assertThat(result.size(), is(2)); + assertThat(result, hasItems(secondUser, thirdUser)); + } + @Test + public void executesSimpleNotCorrectly() throws Exception { - @Test - public void executesSingleEntitySpecificationCorrectly() throws Exception { + flushTestUsers(); - flushTestUsers(); - assertThat(repository.findOne(userHasFirstname("Oliver")), - is(firstUser)); - } + List result = repository.findByLastnameNot("Gierke"); + assertThat(result.size(), is(2)); + assertThat(result, hasItems(secondUser, thirdUser)); + } + @Test + public void returnsSameListIfNoSpecGiven() throws Exception { - @Test - public void returnsNullIfNoEntityFoundForSingleEntitySpecification() - throws Exception { + flushTestUsers(); + assertSameElements(repository.findAll(), repository.findAll((Specification) null)); + } - flushTestUsers(); - assertThat(repository.findOne(userHasLastname("Beauford")), - is(nullValue())); - } + @Test + public void returnsSameListIfNoSortIsGiven() throws Exception { + flushTestUsers(); + assertSameElements(repository.findAll((Sort) null), repository.findAll()); + } - @Test(expected = IncorrectResultSizeDataAccessException.class) - public void throwsExceptionForUnderSpecifiedSingleEntitySpecification() { + @Test + public void returnsSamePageIfNoSpecGiven() throws Exception { - flushTestUsers(); - repository.findOne(userHasFirstnameLike("e")); - } + Pageable pageable = new PageRequest(0, 1); + flushTestUsers(); + assertEquals(repository.findAll(pageable), repository.findAll(null, pageable)); + } - @Test - public void executesCombinedSpecificationsCorrectly() { + @Test + public void returnsAllAsPageIfNoPageableIsGiven() throws Exception { - flushTestUsers(); - Specification spec = - where(userHasFirstname("Oliver")).or(userHasLastname("Arrasz")); - assertThat(repository.findAll(spec).size(), is(2)); - } + flushTestUsers(); + assertEquals(new PageImpl(repository.findAll()), repository.findAll((Pageable) null)); + } + private static void assertSameElements(Collection first, Collection second) { - @Test - public void executesCombinedSpecificationsWithPageableCorrectly() { + for (T element : first) { + assertThat(element, isIn(second)); + } - flushTestUsers(); - Specification spec = - where(userHasFirstname("Oliver")).or(userHasLastname("Arrasz")); + for (T element : second) { + assertThat(element, isIn(first)); + } + } - Page users = repository.findAll(spec, new PageRequest(0, 1)); - assertThat(users.getSize(), is(1)); - assertThat(users.hasPreviousPage(), is(false)); - assertThat(users.getTotalElements(), is(2L)); - } + @Test + public void removeDetachedObject() throws Exception { + flushTestUsers(); - /** - * Flushes test users to the database. - */ - private void flushTestUsers() { + em.detach(firstUser); + repository.delete(firstUser); - firstUser = repository.save(firstUser); - secondUser = repository.save(secondUser); - thirdUser = repository.save(thirdUser); + assertThat(repository.count(), is(2L)); + } - repository.flush(); + @Test + @SuppressWarnings("unchecked") + public void executesPagedSpecificationsCorrectly() throws Exception { - id = firstUser.getId(); + Page result = executeSpecWithSort(null); + assertThat(result.getContent(), anyOf(hasItem(firstUser), hasItem(thirdUser))); + assertThat(result.getContent(), not(hasItem(secondUser))); + } - assertThat(id, is(notNullValue())); - assertThat(secondUser.getId(), is(notNullValue())); - assertThat(thirdUser.getId(), is(notNullValue())); + @Test + public void executesPagedSpecificationsWithSortCorrectly() throws Exception { - assertThat(repository.exists(id), is(true)); - assertThat(repository.exists(secondUser.getId()), is(true)); - assertThat(repository.exists(thirdUser.getId()), is(true)); - } + Page result = executeSpecWithSort(new Sort(Direction.ASC, "lastname")); + assertThat(result.getContent(), hasItem(firstUser)); + assertThat(result.getContent(), not(hasItem(secondUser))); + assertThat(result.getContent(), not(hasItem(thirdUser))); + } - @Test - public void executesMethodWithAnnotatedNamedParametersCorrectly() - throws Exception { + @Test + public void executesPagedSpecificationWithSortCorrectly2() throws Exception { - firstUser = repository.save(firstUser); - secondUser = repository.save(secondUser); + Page result = executeSpecWithSort(new Sort(Direction.DESC, "lastname")); - assertTrue(repository.findByLastnameOrFirstname("Oliver", "Arrasz") - .containsAll(Arrays.asList(firstUser, secondUser))); - } + assertThat(result.getContent(), hasItem(thirdUser)); + assertThat(result.getContent(), not(hasItem(secondUser))); + assertThat(result.getContent(), not(hasItem(firstUser))); + } + @Test + public void executesQueryMethodWithDeepTraversalCorrectly() throws Exception { - @Test - @Ignore - public void executesMethodWithNamedParametersCorrectly() throws Exception { + flushTestUsers(); - firstUser = repository.save(firstUser); - secondUser = repository.save(secondUser); + firstUser.setManager(secondUser); + thirdUser.setManager(firstUser); + repository.save(Arrays.asList(firstUser, thirdUser)); - assertThat(repository.findByLastnameOrFirstnameUnannotated("Oliver", - "Arrasz"), hasItems(firstUser, secondUser)); - } + List result = repository.findByManagerLastname("Arrasz"); + assertThat(result.size(), is(1)); + assertThat(result, hasItem(firstUser)); - @Test - public void executesMethodWithNamedParametersCorrectlyOnMethodsWithQueryCreation() - throws Exception { + result = repository.findByManagerLastname("Gierke"); + assertThat(result.size(), is(1)); + assertThat(result, hasItem(thirdUser)); + } - firstUser = repository.save(firstUser); - secondUser = repository.save(secondUser); + @Test + public void executesFindByColleaguesLastnameCorrectly() throws Exception { - List result = - repository.findByFirstnameOrLastname("Oliver", "Arrasz"); - assertThat(result.size(), is(2)); - assertThat(result, hasItems(firstUser, secondUser)); - } + flushTestUsers(); + firstUser.addColleague(secondUser); + thirdUser.addColleague(firstUser); + repository.save(Arrays.asList(firstUser, thirdUser)); - @Test - public void executesLikeAndOrderByCorrectly() throws Exception { + List result = repository.findByColleaguesLastname(secondUser.getLastname()); - flushTestUsers(); + assertThat(result.size(), is(1)); + assertThat(result, hasItem(firstUser)); - List result = - repository.findByLastnameLikeOrderByFirstnameDesc("%r%"); - assertThat(result.size(), is(2)); - assertEquals(firstUser, result.get(0)); - assertEquals(secondUser, result.get(1)); - } + result = repository.findByColleaguesLastname("Gierke"); + assertThat(result.size(), is(2)); + assertThat(result, hasItems(thirdUser, secondUser)); + } + @Test + public void executesFindByNotNullLastnameCorrectly() throws Exception { - @Test - public void executesNotLikeCorrectly() throws Exception { + flushTestUsers(); + List result = repository.findByLastnameNotNull(); - flushTestUsers(); + assertThat(result.size(), is(3)); + assertThat(result, hasItems(firstUser, secondUser, thirdUser)); + } - List result = repository.findByLastnameNotLike("%er%"); - assertThat(result.size(), is(2)); - assertThat(result, hasItems(secondUser, thirdUser)); - } + @Test + public void executesFindByNullLastnameCorrectly() throws Exception { + flushTestUsers(); + User forthUser = repository.save(new User("Foo", null, "email@address.com")); - @Test - public void executesSimpleNotCorrectly() throws Exception { + List result = repository.findByLastnameNull(); - flushTestUsers(); + assertThat(result.size(), is(1)); + assertThat(result, hasItems(forthUser)); + } - List result = repository.findByLastnameNot("Gierke"); - assertThat(result.size(), is(2)); - assertThat(result, hasItems(secondUser, thirdUser)); - } + @Test + public void findsSortedByLastname() throws Exception { + flushTestUsers(); - @Test - public void returnsSameListIfNoSpecGiven() throws Exception { + List result = repository.findByEmailAddressLike("%@%", new Sort(Direction.ASC, "lastname")); - flushTestUsers(); - assertSameElements(repository.findAll(), - repository.findAll((Specification) null)); - } + assertThat(result.size(), is(3)); + assertThat(result.get(0), is(secondUser)); + assertThat(result.get(1), is(firstUser)); + assertThat(result.get(2), is(thirdUser)); + } + @Test + public void findsUsersBySpringDataNamedQuery() { - @Test - public void returnsSameListIfNoSortIsGiven() throws Exception { + flushTestUsers(); - flushTestUsers(); - assertSameElements(repository.findAll((Sort) null), - repository.findAll()); - } + List result = repository.findBySpringDataNamedQuery("Gierke"); + assertThat(result.size(), is(1)); + assertThat(result, hasItem(firstUser)); + } + private Page executeSpecWithSort(Sort sort) { - @Test - public void returnsSamePageIfNoSpecGiven() throws Exception { + flushTestUsers(); - Pageable pageable = new PageRequest(0, 1); + Specification spec = where(userHasFirstname("Oliver")).or(userHasLastname("Matthews")); - flushTestUsers(); - assertEquals(repository.findAll(pageable), - repository.findAll(null, pageable)); - } - - - @Test - public void returnsAllAsPageIfNoPageableIsGiven() throws Exception { - - flushTestUsers(); - assertEquals(new PageImpl(repository.findAll()), - repository.findAll((Pageable) null)); - } - - - private static void assertSameElements(Collection first, - Collection second) { - - for (T element : first) { - assertThat(element, isIn(second)); - } - - for (T element : second) { - assertThat(element, isIn(first)); - } - } - - - @Test - public void removeDetachedObject() throws Exception { - - flushTestUsers(); - - em.detach(firstUser); - repository.delete(firstUser); - - assertThat(repository.count(), is(2L)); - } - - - @Test - @SuppressWarnings("unchecked") - public void executesPagedSpecificationsCorrectly() throws Exception { - - Page result = executeSpecWithSort(null); - assertThat(result.getContent(), - anyOf(hasItem(firstUser), hasItem(thirdUser))); - assertThat(result.getContent(), not(hasItem(secondUser))); - } - - - @Test - public void executesPagedSpecificationsWithSortCorrectly() throws Exception { - - Page result = - executeSpecWithSort(new Sort(Direction.ASC, "lastname")); - - assertThat(result.getContent(), hasItem(firstUser)); - assertThat(result.getContent(), not(hasItem(secondUser))); - assertThat(result.getContent(), not(hasItem(thirdUser))); - } - - - @Test - public void executesPagedSpecificationWithSortCorrectly2() throws Exception { - - Page result = - executeSpecWithSort(new Sort(Direction.DESC, "lastname")); - - assertThat(result.getContent(), hasItem(thirdUser)); - assertThat(result.getContent(), not(hasItem(secondUser))); - assertThat(result.getContent(), not(hasItem(firstUser))); - } - - - @Test - public void executesQueryMethodWithDeepTraversalCorrectly() - throws Exception { - - flushTestUsers(); - - firstUser.setManager(secondUser); - thirdUser.setManager(firstUser); - repository.save(Arrays.asList(firstUser, thirdUser)); - - List result = repository.findByManagerLastname("Arrasz"); - - assertThat(result.size(), is(1)); - assertThat(result, hasItem(firstUser)); - - result = repository.findByManagerLastname("Gierke"); - assertThat(result.size(), is(1)); - assertThat(result, hasItem(thirdUser)); - } - - - @Test - public void executesFindByColleaguesLastnameCorrectly() throws Exception { - - flushTestUsers(); - - firstUser.addColleague(secondUser); - thirdUser.addColleague(firstUser); - repository.save(Arrays.asList(firstUser, thirdUser)); - - List result = - repository.findByColleaguesLastname(secondUser.getLastname()); - - assertThat(result.size(), is(1)); - assertThat(result, hasItem(firstUser)); - - result = repository.findByColleaguesLastname("Gierke"); - assertThat(result.size(), is(2)); - assertThat(result, hasItems(thirdUser, secondUser)); - } - - - @Test - public void executesFindByNotNullLastnameCorrectly() throws Exception { - - flushTestUsers(); - List result = repository.findByLastnameNotNull(); - - assertThat(result.size(), is(3)); - assertThat(result, hasItems(firstUser, secondUser, thirdUser)); - } - - - @Test - public void executesFindByNullLastnameCorrectly() throws Exception { - - flushTestUsers(); - User forthUser = - repository.save(new User("Foo", null, "email@address.com")); - - List result = repository.findByLastnameNull(); - - assertThat(result.size(), is(1)); - assertThat(result, hasItems(forthUser)); - } - - - @Test - public void findsSortedByLastname() throws Exception { - - flushTestUsers(); - - List result = - repository.findByEmailAddressLike("%@%", new Sort( - Direction.ASC, "lastname")); - - assertThat(result.size(), is(3)); - assertThat(result.get(0), is(secondUser)); - assertThat(result.get(1), is(firstUser)); - assertThat(result.get(2), is(thirdUser)); - } - - - @Test - public void findsUsersBySpringDataNamedQuery() { - - flushTestUsers(); - - List result = repository.findBySpringDataNamedQuery("Gierke"); - assertThat(result.size(), is(1)); - assertThat(result, hasItem(firstUser)); - } - - - private Page executeSpecWithSort(Sort sort) { - - flushTestUsers(); - - Specification spec = - where(userHasFirstname("Oliver")).or( - userHasLastname("Matthews")); - - Page result = - repository.findAll(spec, new PageRequest(0, 1, sort)); - assertThat(result.getTotalElements(), is(2L)); - return result; - } + Page result = repository.findAll(spec, new PageRequest(0, 1, sort)); + assertThat(result.getTotalElements(), is(2L)); + return result; + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/config/AbstractRepositoryConfigTests.java b/src/test/java/org/springframework/data/jpa/repository/config/AbstractRepositoryConfigTests.java index 07a861d57..da8076fd9 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/AbstractRepositoryConfigTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/AbstractRepositoryConfigTests.java @@ -25,7 +25,6 @@ import org.springframework.data.jpa.repository.sample.RoleRepository; import org.springframework.data.jpa.repository.sample.UserRepository; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - /** * Abstract base class for integration test for namespace configuration. * @@ -34,24 +33,23 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) public abstract class AbstractRepositoryConfigTests { - @Autowired(required = false) - UserRepository userRepository; + @Autowired(required = false) + UserRepository userRepository; - @Autowired(required = false) - RoleRepository roleRepository; + @Autowired(required = false) + RoleRepository roleRepository; - @Autowired(required = false) - AuditableUserRepository auditableUserRepository; + @Autowired(required = false) + AuditableUserRepository auditableUserRepository; + /** + * Asserts that context creation detects 3 repository beans. + */ + @Test + public void testContextCreation() { - /** - * Asserts that context creation detects 3 repository beans. - */ - @Test - public void testContextCreation() { - - assertNotNull(userRepository); - assertNotNull(roleRepository); - assertNotNull(auditableUserRepository); - } + assertNotNull(userRepository); + assertNotNull(roleRepository); + assertNotNull(auditableUserRepository); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java b/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java index 6cb1598fe..dbea6ed1f 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/AuditingBeanDefinitionParserTests.java @@ -24,7 +24,6 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; - /** * Integration tests for {@link AuditingBeanDefinitionParser}. * @@ -32,31 +31,25 @@ import org.springframework.core.io.ClassPathResource; */ public class AuditingBeanDefinitionParserTests { - @Test - public void settingDatesIsConfigured() throws Exception { + @Test + public void settingDatesIsConfigured() throws Exception { - assertSetDatesIsSetTo("auditing/auditing-namespace-context.xml", "true"); - } + assertSetDatesIsSetTo("auditing/auditing-namespace-context.xml", "true"); + } + @Test + public void notSettingDatesIsConfigured() throws Exception { - @Test - public void notSettingDatesIsConfigured() throws Exception { + assertSetDatesIsSetTo("auditing/auditing-namespace-context2.xml", "false"); + } - assertSetDatesIsSetTo("auditing/auditing-namespace-context2.xml", - "false"); - } + private void assertSetDatesIsSetTo(String configFile, String value) { - - private void assertSetDatesIsSetTo(String configFile, String value) { - - XmlBeanFactory factory = - new XmlBeanFactory(new ClassPathResource(configFile)); - BeanDefinition definition = - factory.getBeanDefinition(AuditingBeanDefinitionParser.AUDITING_ENTITY_LISTENER_CLASS_NAME); - PropertyValue propertyValue = - definition.getPropertyValues().getPropertyValue( - "dateTimeForNow"); - assertThat(propertyValue, is(notNullValue())); - assertThat((String) propertyValue.getValue(), is(value)); - } + XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(configFile)); + BeanDefinition definition = factory + .getBeanDefinition(AuditingBeanDefinitionParser.AUDITING_ENTITY_LISTENER_CLASS_NAME); + PropertyValue propertyValue = definition.getPropertyValues().getPropertyValue("dateTimeForNow"); + assertThat(propertyValue, is(notNullValue())); + assertThat((String) propertyValue.getValue(), is(value)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/config/CustomRepositoryFactoryConfigTests.java b/src/test/java/org/springframework/data/jpa/repository/config/CustomRepositoryFactoryConfigTests.java index 5d2eae09c..876b8bfe6 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/CustomRepositoryFactoryConfigTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/CustomRepositoryFactoryConfigTests.java @@ -28,16 +28,14 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.Assert; - /** - * Annotation to exclude repository interfaces from being picked up and thus in - * consequence getting an instance being created. + * Annotation to exclude repository interfaces from being picked up and thus in consequence getting an instance being + * created. *

- * This will typically be used when providing an extended base interface for all - * repositories in combination with a custom repository base class to implement - * methods declared in that intermediate interface. In this case you typically - * derive your concrete repository interfaces from the intermediate one but - * don't want to create a Spring bean for the intermediate interface. + * This will typically be used when providing an extended base interface for all repositories in combination with a + * custom repository base class to implement methods declared in that intermediate interface. In this case you typically + * derive your concrete repository interfaces from the intermediate one but don't want to create a Spring bean for the + * intermediate interface. * * @author Oliver Gierke */ @@ -45,44 +43,40 @@ import org.springframework.util.Assert; @ContextConfiguration(locations = "classpath:config/namespace-customfactory-context.xml") public class CustomRepositoryFactoryConfigTests { - @Autowired(required = false) - UserCustomExtendedRepository userRepository; + @Autowired(required = false) + UserCustomExtendedRepository userRepository; - @Autowired - DelegatingTransactionManager transactionManager; + @Autowired + DelegatingTransactionManager transactionManager; + @Before + public void setup() { - @Before - public void setup() { + transactionManager.resetCount(); + } - transactionManager.resetCount(); - } + @Test(expected = UnsupportedOperationException.class) + public void testCustomFactoryUsed() { + Assert.notNull(userRepository); + userRepository.customMethod(1); + } - @Test(expected = UnsupportedOperationException.class) - public void testCustomFactoryUsed() { + @Test + public void reconfiguresTransactionalMethodWithoutGenericParameter() { - Assert.notNull(userRepository); - userRepository.customMethod(1); - } + userRepository.findAll(); + assertFalse(transactionManager.getDefinition().isReadOnly()); + assertThat(transactionManager.getDefinition().getTimeout(), is(10)); + } - @Test - public void reconfiguresTransactionalMethodWithoutGenericParameter() { + @Test + public void reconfiguresTransactionalMethodWithGenericParameter() { - userRepository.findAll(); + userRepository.findOne(1); - assertFalse(transactionManager.getDefinition().isReadOnly()); - assertThat(transactionManager.getDefinition().getTimeout(), is(10)); - } - - - @Test - public void reconfiguresTransactionalMethodWithGenericParameter() { - - userRepository.findOne(1); - - assertFalse(transactionManager.getDefinition().isReadOnly()); - assertThat(transactionManager.getDefinition().getTimeout(), is(10)); - } + assertFalse(transactionManager.getDefinition().isReadOnly()); + assertThat(transactionManager.getDefinition().getTimeout(), is(10)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParserTests.java b/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParserTests.java index b4f22ae63..d9c50f4a7 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParserTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/JpaRepositoryConfigDefinitionParserTests.java @@ -24,7 +24,6 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; - /** * Integration test for {@link JpaRepositoryConfigDefinitionParser}. * @@ -32,22 +31,17 @@ import org.springframework.core.io.ClassPathResource; */ public class JpaRepositoryConfigDefinitionParserTests { - @Test - public void getsTransactionManagerSet() throws Exception { + @Test + public void getsTransactionManagerSet() throws Exception { - XmlBeanFactory factory = - new XmlBeanFactory(new ClassPathResource( - "multiple-entity-manager-integration-context.xml")); + XmlBeanFactory factory = new XmlBeanFactory( + new ClassPathResource("multiple-entity-manager-integration-context.xml")); - BeanDefinition definition = - factory.getBeanDefinition("auditableUserRepository"); - assertThat(definition, is(notNullValue())); + BeanDefinition definition = factory.getBeanDefinition("auditableUserRepository"); + assertThat(definition, is(notNullValue())); - PropertyValue transactionManager = - definition.getPropertyValues().getPropertyValue( - "transactionManager"); - assertThat(transactionManager, is(notNullValue())); - assertThat(transactionManager.getValue().toString(), - is("transactionManager-2")); - } + PropertyValue transactionManager = definition.getPropertyValues().getPropertyValue("transactionManager"); + assertThat(transactionManager, is(notNullValue())); + assertThat(transactionManager.getValue().toString(), is("transactionManager-2")); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/config/QueryLookupStrategyTests.java b/src/test/java/org/springframework/data/jpa/repository/config/QueryLookupStrategyTests.java index 9be590a28..737d03a0b 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/QueryLookupStrategyTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/QueryLookupStrategyTests.java @@ -28,7 +28,6 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - /** * Integration test for XML configuration of {@link QueryLookupStrategy.Key}s. * @@ -38,22 +37,17 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ContextConfiguration(locations = "classpath:config/lookup-strategies-context.xml") public class QueryLookupStrategyTests { - @Autowired - ApplicationContext context; + @Autowired + ApplicationContext context; + /** + * Assert that {@link QueryLookupStrategy#USE_DECLARED_QUERY} is being set on the factory if configured. + */ + @Test + public void assertUseDeclaredQuery() { - /** - * Assert that {@link QueryLookupStrategy#USE_DECLARED_QUERY} is being set - * on the factory if configured. - */ - @Test - public void assertUseDeclaredQuery() { + JpaRepositoryFactoryBean factory = context.getBean("&roleRepository", JpaRepositoryFactoryBean.class); - JpaRepositoryFactoryBean factory = - context.getBean("&roleRepository", - JpaRepositoryFactoryBean.class); - - assertEquals(Key.USE_DECLARED_QUERY, - getField(factory, "queryLookupStrategyKey")); - } + assertEquals(Key.USE_DECLARED_QUERY, getField(factory, "queryLookupStrategyKey")); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/config/RepositoryAutoConfigTests.java b/src/test/java/org/springframework/data/jpa/repository/config/RepositoryAutoConfigTests.java index 46f18ece3..d07598a64 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/RepositoryAutoConfigTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/RepositoryAutoConfigTests.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.config; import org.springframework.test.context.ContextConfiguration; - /** * Integration test to test repository auto configuration. * diff --git a/src/test/java/org/springframework/data/jpa/repository/config/RepositoryConfigTests.java b/src/test/java/org/springframework/data/jpa/repository/config/RepositoryConfigTests.java index 71705347f..d9c1f707b 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/RepositoryConfigTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/RepositoryConfigTests.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.config; import org.springframework.test.context.ContextConfiguration; - /** * Integration test for repository namespace configuration. * diff --git a/src/test/java/org/springframework/data/jpa/repository/config/TypeFilterConfigTest.java b/src/test/java/org/springframework/data/jpa/repository/config/TypeFilterConfigTest.java index 2bcdfd0a7..c7fc557a4 100644 --- a/src/test/java/org/springframework/data/jpa/repository/config/TypeFilterConfigTest.java +++ b/src/test/java/org/springframework/data/jpa/repository/config/TypeFilterConfigTest.java @@ -19,29 +19,26 @@ import static org.junit.Assert.*; import org.springframework.test.context.ContextConfiguration; - /** - * Integration test to test - * {@link org.springframework.core.type.filter.TypeFilter} integration into - * namespace. + * Integration test to test {@link org.springframework.core.type.filter.TypeFilter} integration into namespace. * * @author Oliver Gierke */ @ContextConfiguration(locations = "classpath:config/namespace-autoconfig-typefilter-context.xml") public class TypeFilterConfigTest extends AbstractRepositoryConfigTests { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.config.AbstractRepositoryConfigTests - * #testContextCreation() - */ - @Override - public void testContextCreation() { + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.config.AbstractRepositoryConfigTests + * #testContextCreation() + */ + @Override + public void testContextCreation() { - assertNotNull(userRepository); - assertNotNull(roleRepository); - assertNull(auditableUserRepository); - } + assertNotNull(userRepository); + assertNotNull(roleRepository); + assertNull(auditableUserRepository); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepository.java b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepository.java index 34e17ce13..2d0122034 100644 --- a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepository.java @@ -22,37 +22,32 @@ import javax.persistence.EntityManager; import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.SimpleJpaRepository; - /** - * Sample custom repository base class implementing common custom functionality - * for all derived repository instances. + * Sample custom repository base class implementing common custom functionality for all derived repository instances. * * @author Oliver Gierke */ -public class CustomGenericJpaRepository extends - SimpleJpaRepository implements CustomGenericRepository { +public class CustomGenericJpaRepository extends SimpleJpaRepository implements + CustomGenericRepository { - /** - * @param domainClass - * @param entityManager - */ - public CustomGenericJpaRepository(JpaEntityInformation metadata, - EntityManager entityManager) { + /** + * @param domainClass + * @param entityManager + */ + public CustomGenericJpaRepository(JpaEntityInformation metadata, EntityManager entityManager) { - super(metadata, entityManager); - } + super(metadata, entityManager); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.custom.CustomGenericRepository + * #customMethod(java.io.Serializable) + */ + public T customMethod(ID id) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.custom.CustomGenericRepository - * #customMethod(java.io.Serializable) - */ - public T customMethod(ID id) { - - throw new UnsupportedOperationException( - "Forced exception for testing purposes."); - } + throw new UnsupportedOperationException("Forced exception for testing purposes."); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactory.java b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactory.java index 83fa73564..8f3896e3a 100644 --- a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactory.java +++ b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactory.java @@ -26,55 +26,47 @@ import org.springframework.data.jpa.repository.support.JpaEntityInformation; import org.springframework.data.jpa.repository.support.JpaRepositoryFactory; import org.springframework.data.repository.core.RepositoryMetadata; - /** - * Sample implementation of a custom {@link JpaRepositoryFactory} to use a - * custom repository base class. + * Sample implementation of a custom {@link JpaRepositoryFactory} to use a custom repository base class. * * @author Oliver Gierke */ public class CustomGenericJpaRepositoryFactory extends JpaRepositoryFactory { - /** - * @param entityManager - */ - public CustomGenericJpaRepositoryFactory(EntityManager entityManager) { + /** + * @param entityManager + */ + public CustomGenericJpaRepositoryFactory(EntityManager entityManager) { - super(entityManager); - } + super(entityManager); + } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.support.GenericJpaRepositoryFactory + * #getTargetRepository(java.lang.Class, javax.persistence.EntityManager) + */ + @Override + @SuppressWarnings("unchecked") + protected JpaRepository getTargetRepository(RepositoryMetadata metadata, EntityManager em) { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.support.GenericJpaRepositoryFactory - * #getTargetRepository(java.lang.Class, javax.persistence.EntityManager) - */ - @Override - @SuppressWarnings("unchecked") - protected JpaRepository getTargetRepository( - RepositoryMetadata metadata, EntityManager em) { + JpaEntityInformation entityMetadata = mock(JpaEntityInformation.class); + when(entityMetadata.getJavaType()).thenReturn((Class) metadata.getDomainClass()); + return new CustomGenericJpaRepository(entityMetadata, em); + } - JpaEntityInformation entityMetadata = - mock(JpaEntityInformation.class); - when(entityMetadata.getJavaType()).thenReturn( - (Class) metadata.getDomainClass()); - return new CustomGenericJpaRepository( - entityMetadata, em); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.repository.support.RepositoryFactorySupport# + * getRepositoryBaseClass() + */ + @Override + protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.repository.support.RepositoryFactorySupport# - * getRepositoryBaseClass() - */ - @Override - protected Class getRepositoryBaseClass(RepositoryMetadata metadata) { - - return CustomGenericJpaRepository.class; - } + return CustomGenericJpaRepository.class; + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactoryBean.java b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactoryBean.java index a52a0fbcc..e9465b8cb 100644 --- a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactoryBean.java +++ b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericJpaRepositoryFactoryBean.java @@ -23,25 +23,24 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean; import org.springframework.data.repository.core.support.RepositoryFactorySupport; - /** * {@link JpaRepositoryFactoryBean} to return a custom repository base class. * * @author Gil Markham * @author Oliver Gierke */ -public class CustomGenericJpaRepositoryFactoryBean> - extends JpaRepositoryFactoryBean { +public class CustomGenericJpaRepositoryFactoryBean> extends + JpaRepositoryFactoryBean { - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.support. - * GenericJpaRepositoryFactoryBean#getFactory() - */ - @Override - protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) { + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.support. + * GenericJpaRepositoryFactoryBean#getFactory() + */ + @Override + protected RepositoryFactorySupport createRepositoryFactory(EntityManager em) { - return new CustomGenericJpaRepositoryFactory(em); - } + return new CustomGenericJpaRepositoryFactory(em); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericRepository.java b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericRepository.java index c5c0fc315..24a00dd62 100644 --- a/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/custom/CustomGenericRepository.java @@ -18,27 +18,24 @@ package org.springframework.data.jpa.repository.custom; import java.io.Serializable; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.repository.NoRepositoryBean; import org.springframework.data.repository.CrudRepository; - +import org.springframework.data.repository.NoRepositoryBean; /** - * Extension of {@link CrudRepository} to be added on a custom repository base - * class. This tests the facility to implement custom base class functionality - * for all repository instances derived from this interface and implementation + * Extension of {@link CrudRepository} to be added on a custom repository base class. This tests the facility to + * implement custom base class functionality for all repository instances derived from this interface and implementation * base class. * * @author Oliver Gierke */ @NoRepositoryBean -public interface CustomGenericRepository extends - JpaRepository { +public interface CustomGenericRepository extends JpaRepository { - /** - * Custom sample method. - * - * @param id - * @return - */ - T customMethod(ID id); + /** + * Custom sample method. + * + * @param id + * @return + */ + T customMethod(ID id); } diff --git a/src/test/java/org/springframework/data/jpa/repository/custom/UserCustomExtendedRepository.java b/src/test/java/org/springframework/data/jpa/repository/custom/UserCustomExtendedRepository.java index 44cbb99e7..dbf89c00d 100644 --- a/src/test/java/org/springframework/data/jpa/repository/custom/UserCustomExtendedRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/custom/UserCustomExtendedRepository.java @@ -20,28 +20,24 @@ import java.util.List; import org.springframework.data.jpa.domain.sample.User; import org.springframework.transaction.annotation.Transactional; - /** - * Custom Extended repository interface for a {@code User}. This relies on the - * custom intermediate repository interface {@link CustomGenericRepository}. + * Custom Extended repository interface for a {@code User}. This relies on the custom intermediate repository interface + * {@link CustomGenericRepository}. * * @author Oliver Gierke */ -public interface UserCustomExtendedRepository extends - CustomGenericRepository { +public interface UserCustomExtendedRepository extends CustomGenericRepository { - /** - * Sample method to test reconfiguring transactions on CRUD methods in - * combination with custom factory. - * - * @see #421 - */ + /** + * Sample method to test reconfiguring transactions on CRUD methods in combination with custom factory. + * + * @see #421 + */ - @Transactional(readOnly = false, timeout = 10) - List findAll(); + @Transactional(readOnly = false, timeout = 10) + List findAll(); - - @Transactional(readOnly = false, timeout = 10) - User findOne(Integer id); + @Transactional(readOnly = false, timeout = 10) + User findOne(Integer id); } \ No newline at end of file diff --git a/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryExecutionUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryExecutionUnitTests.java index 96ba0e380..7de43cc7d 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryExecutionUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryExecutionUnitTests.java @@ -29,7 +29,6 @@ import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.data.jpa.repository.query.JpaQueryExecution.ModifyingExecution; - /** * Unit test for {@link QueryExecution}. * @@ -38,88 +37,79 @@ import org.springframework.data.jpa.repository.query.JpaQueryExecution.Modifying @RunWith(MockitoJUnitRunner.class) public class JpaQueryExecutionUnitTests { - @Mock - EntityManager em; - @Mock - AbstractStringBasedJpaQuery jpaQuery; - @Mock - Query query; - @Mock - JpaQueryMethod method; + @Mock + EntityManager em; + @Mock + AbstractStringBasedJpaQuery jpaQuery; + @Mock + Query query; + @Mock + JpaQueryMethod method; + @Test(expected = IllegalArgumentException.class) + public void rejectsNullQuery() { - @Test(expected = IllegalArgumentException.class) - public void rejectsNullQuery() { + new StubQueryExecution().execute(null, new Object[] {}); + } - new StubQueryExecution().execute(null, new Object[] {}); - } + @Test(expected = IllegalArgumentException.class) + public void rejectsNullBinder() throws Exception { + new StubQueryExecution().execute(jpaQuery, null); + } - @Test(expected = IllegalArgumentException.class) - public void rejectsNullBinder() throws Exception { + @Test + public void transformsNoResultExceptionToNull() { - new StubQueryExecution().execute(jpaQuery, null); - } + assertThat(new JpaQueryExecution() { + @Override + protected Object doExecute(AbstractJpaQuery query, Object[] values) { - @Test - public void transformsNoResultExceptionToNull() { + return null; + } + }.execute(jpaQuery, new Object[] {}), is(nullValue())); + } - assertThat(new JpaQueryExecution() { + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void modifyingExecutionClearsEntityManagerIfSet() { - @Override - protected Object doExecute(AbstractJpaQuery query, Object[] values) { + when(query.executeUpdate()).thenReturn(0); + when(method.getReturnType()).thenReturn((Class) void.class); + when(jpaQuery.createQuery(Mockito.any(Object[].class))).thenReturn(query); - return null; - } - }.execute(jpaQuery, new Object[] {}), is(nullValue())); - } + ModifyingExecution execution = new ModifyingExecution(method, em); + execution.execute(jpaQuery, new Object[] {}); + verify(em, times(1)).clear(); + } - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void modifyingExecutionClearsEntityManagerIfSet() { + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void allowsMethodReturnTypesForModifyingQuery() throws Exception { - when(query.executeUpdate()).thenReturn(0); - when(method.getReturnType()).thenReturn((Class) void.class); - when(jpaQuery.createQuery(Mockito.any(Object[].class))).thenReturn( - query); + when(method.getReturnType()).thenReturn((Class) void.class, (Class) int.class, (Class) Integer.class); - ModifyingExecution execution = new ModifyingExecution(method, em); - execution.execute(jpaQuery, new Object[] {}); + new ModifyingExecution(method, em); + new ModifyingExecution(method, em); + new ModifyingExecution(method, em); + } - verify(em, times(1)).clear(); - } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test(expected = IllegalArgumentException.class) + public void modifyingExecutionRejectsNonIntegerOrVoidReturnType() throws Exception { + when(method.getReturnType()).thenReturn((Class) Long.class); + new ModifyingExecution(method, em); + } - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void allowsMethodReturnTypesForModifyingQuery() throws Exception { + static class StubQueryExecution extends JpaQueryExecution { - when(method.getReturnType()).thenReturn((Class) void.class, - (Class) int.class, (Class) Integer.class); + @Override + protected Object doExecute(AbstractJpaQuery query, Object[] values) { - new ModifyingExecution(method, em); - new ModifyingExecution(method, em); - new ModifyingExecution(method, em); - } - - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Test(expected = IllegalArgumentException.class) - public void modifyingExecutionRejectsNonIntegerOrVoidReturnType() - throws Exception { - - when(method.getReturnType()).thenReturn((Class) Long.class); - new ModifyingExecution(method, em); - } - - static class StubQueryExecution extends JpaQueryExecution { - - @Override - protected Object doExecute(AbstractJpaQuery query, Object[] values) { - - return null; - } - } + return null; + } + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryMethodUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryMethodUnitTests.java index 771e70e85..ab8742469 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryMethodUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/JpaQueryMethodUnitTests.java @@ -39,7 +39,6 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat import org.springframework.data.repository.query.QueryMethod; import org.springframework.data.repository.query.QueryMethod.Type; - /** * Unit test for {@link QueryMethod}. * @@ -48,230 +47,175 @@ import org.springframework.data.repository.query.QueryMethod.Type; @RunWith(MockitoJUnitRunner.class) public class JpaQueryMethodUnitTests { - static final Class DOMAIN_CLASS = User.class; - static final String METHOD_NAME = "findByFirstname"; + static final Class DOMAIN_CLASS = User.class; + static final String METHOD_NAME = "findByFirstname"; - @Mock - QueryExtractor extractor; - @Mock - RepositoryMetadata metadata; + @Mock + QueryExtractor extractor; + @Mock + RepositoryMetadata metadata; - Method repositoryMethod, invalidReturnType, pageableAndSort, pageableTwice, - sortableTwice, modifyingMethod; + Method repositoryMethod, invalidReturnType, pageableAndSort, pageableTwice, sortableTwice, modifyingMethod; + /** + * @throws Exception + */ + @Before + public void setUp() throws Exception { - /** - * @throws Exception - */ - @Before - public void setUp() throws Exception { + repositoryMethod = UserRepository.class.getMethod("findByLastname", String.class); - repositoryMethod = - UserRepository.class.getMethod("findByLastname", String.class); + invalidReturnType = InvalidRepository.class.getMethod(METHOD_NAME, String.class, Pageable.class); + pageableAndSort = InvalidRepository.class.getMethod(METHOD_NAME, String.class, Pageable.class, Sort.class); + pageableTwice = InvalidRepository.class.getMethod(METHOD_NAME, String.class, Pageable.class, Pageable.class); - invalidReturnType = - InvalidRepository.class.getMethod(METHOD_NAME, String.class, - Pageable.class); - pageableAndSort = - InvalidRepository.class.getMethod(METHOD_NAME, String.class, - Pageable.class, Sort.class); - pageableTwice = - InvalidRepository.class.getMethod(METHOD_NAME, String.class, - Pageable.class, Pageable.class); + sortableTwice = InvalidRepository.class.getMethod(METHOD_NAME, String.class, Sort.class, Sort.class); + modifyingMethod = UserRepository.class.getMethod("renameAllUsersTo", String.class); + } - sortableTwice = - InvalidRepository.class.getMethod(METHOD_NAME, String.class, - Sort.class, Sort.class); - modifyingMethod = - UserRepository.class - .getMethod("renameAllUsersTo", String.class); - } + @Test + public void testname() { + JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, metadata, extractor); - @Test - public void testname() { + assertEquals("User.findByLastname", method.getNamedQueryName()); + assertThat(method.getType(), is(Type.COLLECTION)); + } - JpaQueryMethod method = - new JpaQueryMethod(repositoryMethod, metadata, extractor); + @Test(expected = IllegalArgumentException.class) + public void preventsNullRepositoryMethod() { - assertEquals("User.findByLastname", method.getNamedQueryName()); - assertThat(method.getType(), is(Type.COLLECTION)); - } + new JpaQueryMethod(null, metadata, extractor); + } + @Test(expected = IllegalArgumentException.class) + public void preventsNullQueryExtractor() { - @Test(expected = IllegalArgumentException.class) - public void preventsNullRepositoryMethod() { + new JpaQueryMethod(repositoryMethod, metadata, null); + } - new JpaQueryMethod(null, metadata, extractor); - } + @Test + public void returnsCorrectName() { + JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, metadata, extractor); + assertEquals(repositoryMethod.getName(), method.getName()); + } - @Test(expected = IllegalArgumentException.class) - public void preventsNullQueryExtractor() { + @Test + public void returnsQueryIfAvailable() throws Exception { - new JpaQueryMethod(repositoryMethod, metadata, null); - } + JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, metadata, extractor); + assertNull(method.getAnnotatedQuery()); - @Test - public void returnsCorrectName() { + Method repositoryMethod = UserRepository.class.getMethod("findByAnnotatedQuery", String.class); - JpaQueryMethod method = - new JpaQueryMethod(repositoryMethod, metadata, extractor); - assertEquals(repositoryMethod.getName(), method.getName()); - } + assertNotNull(new JpaQueryMethod(repositoryMethod, metadata, extractor).getAnnotatedQuery()); + } + @Test(expected = IllegalStateException.class) + public void rejectsInvalidReturntypeOnPagebleFinder() { - @Test - public void returnsQueryIfAvailable() throws Exception { + new JpaQueryMethod(invalidReturnType, metadata, extractor); + } - JpaQueryMethod method = - new JpaQueryMethod(repositoryMethod, metadata, extractor); + @Test(expected = IllegalStateException.class) + public void rejectsPageableAndSortInFinderMethod() { - assertNull(method.getAnnotatedQuery()); + new JpaQueryMethod(pageableAndSort, metadata, extractor); + } - Method repositoryMethod = - UserRepository.class.getMethod("findByAnnotatedQuery", - String.class); + @Test(expected = IllegalStateException.class) + public void rejectsTwoPageableParameters() { - assertNotNull(new JpaQueryMethod(repositoryMethod, metadata, extractor) - .getAnnotatedQuery()); - } + new JpaQueryMethod(pageableTwice, metadata, extractor); + } + @Test(expected = IllegalStateException.class) + public void rejectsTwoSortableParameters() { - @Test(expected = IllegalStateException.class) - public void rejectsInvalidReturntypeOnPagebleFinder() { + new JpaQueryMethod(sortableTwice, metadata, extractor); + } - new JpaQueryMethod(invalidReturnType, metadata, extractor); - } + @Test + public void recognizesModifyingMethod() { + JpaQueryMethod method = new JpaQueryMethod(modifyingMethod, metadata, extractor); + assertTrue(method.isModifyingQuery()); + } - @Test(expected = IllegalStateException.class) - public void rejectsPageableAndSortInFinderMethod() { + @Test(expected = IllegalArgumentException.class) + public void rejectsModifyingMethodWithPageable() throws Exception { - new JpaQueryMethod(pageableAndSort, metadata, extractor); - } + Method method = InvalidRepository.class.getMethod("updateMethod", String.class, Pageable.class); + new JpaQueryMethod(method, metadata, extractor); + } - @Test(expected = IllegalStateException.class) - public void rejectsTwoPageableParameters() { + @Test(expected = IllegalArgumentException.class) + public void rejectsModifyingMethodWithSort() throws Exception { - new JpaQueryMethod(pageableTwice, metadata, extractor); - } + Method method = InvalidRepository.class.getMethod("updateMethod", String.class, Sort.class); + new JpaQueryMethod(method, metadata, extractor); + } - @Test(expected = IllegalStateException.class) - public void rejectsTwoSortableParameters() { + @Test + public void discoversHintsCorrectly() { - new JpaQueryMethod(sortableTwice, metadata, extractor); - } + JpaQueryMethod method = new JpaQueryMethod(repositoryMethod, metadata, extractor); + List hints = method.getHints(); + assertNotNull(hints); + assertThat(hints.get(0).name(), is("foo")); + assertThat(hints.get(0).value(), is("bar")); + } - @Test - public void recognizesModifyingMethod() { + @Test + public void calculatesNamedQueryNamesCorrectly() throws SecurityException, NoSuchMethodException { - JpaQueryMethod method = - new JpaQueryMethod(modifyingMethod, metadata, extractor); - assertTrue(method.isModifyingQuery()); - } + JpaQueryMethod queryMethod = new JpaQueryMethod(repositoryMethod, metadata, extractor); + assertThat(queryMethod.getNamedQueryName(), is("User.findByLastname")); + RepositoryMetadata metadata = new DefaultRepositoryMetadata(UserRepository.class); + Method method = UserRepository.class.getMethod("renameAllUsersTo", String.class); + queryMethod = new JpaQueryMethod(method, metadata, extractor); + assertThat(queryMethod.getNamedQueryName(), is("User.renameAllUsersTo")); - @Test(expected = IllegalArgumentException.class) - public void rejectsModifyingMethodWithPageable() throws Exception { + method = UserRepository.class.getMethod("findSpecialUsersByLastname", String.class); + queryMethod = new JpaQueryMethod(method, metadata, extractor); + assertThat(queryMethod.getNamedQueryName(), is("SpecialUser.findSpecialUsersByLastname")); + } - Method method = - InvalidRepository.class.getMethod("updateMethod", String.class, - Pageable.class); + /** + * Interface to define invalid repository methods for testing. + * + * @author Oliver Gierke + */ + static interface InvalidRepository { - new JpaQueryMethod(method, metadata, extractor); - } + // Invalid return type + User findByFirstname(String firstname, Pageable pageable); + // Should not use Pageable *and* Sort + Page findByFirstname(String firstname, Pageable pageable, Sort sort); - @Test(expected = IllegalArgumentException.class) - public void rejectsModifyingMethodWithSort() throws Exception { + // Must not use two Pageables + Page findByFirstname(String firstname, Pageable first, Pageable second); - Method method = - InvalidRepository.class.getMethod("updateMethod", String.class, - Sort.class); + // Must not use two Pageables + Page findByFirstname(String firstname, Sort first, Sort second); - new JpaQueryMethod(method, metadata, extractor); - } + // Not backed by a named query or @Query annotation + @Modifying + void updateMethod(String firstname); + // Modifying and Pageable is not allowed + @Modifying + Page updateMethod(String firstname, Pageable pageable); - @Test - public void discoversHintsCorrectly() { - - JpaQueryMethod method = - new JpaQueryMethod(repositoryMethod, metadata, extractor); - List hints = method.getHints(); - - assertNotNull(hints); - assertThat(hints.get(0).name(), is("foo")); - assertThat(hints.get(0).value(), is("bar")); - } - - - @Test - public void calculatesNamedQueryNamesCorrectly() throws SecurityException, - NoSuchMethodException { - - JpaQueryMethod queryMethod = - new JpaQueryMethod(repositoryMethod, metadata, extractor); - assertThat(queryMethod.getNamedQueryName(), is("User.findByLastname")); - - RepositoryMetadata metadata = - new DefaultRepositoryMetadata(UserRepository.class); - Method method = - UserRepository.class - .getMethod("renameAllUsersTo", String.class); - queryMethod = new JpaQueryMethod(method, metadata, extractor); - assertThat(queryMethod.getNamedQueryName(), is("User.renameAllUsersTo")); - - method = - UserRepository.class.getMethod("findSpecialUsersByLastname", - String.class); - queryMethod = new JpaQueryMethod(method, metadata, extractor); - assertThat(queryMethod.getNamedQueryName(), - is("SpecialUser.findSpecialUsersByLastname")); - } - - /** - * Interface to define invalid repository methods for testing. - * - * @author Oliver Gierke - */ - static interface InvalidRepository { - - // Invalid return type - User findByFirstname(String firstname, Pageable pageable); - - - // Should not use Pageable *and* Sort - Page findByFirstname(String firstname, Pageable pageable, - Sort sort); - - - // Must not use two Pageables - Page findByFirstname(String firstname, Pageable first, - Pageable second); - - - // Must not use two Pageables - Page findByFirstname(String firstname, Sort first, Sort second); - - - // Not backed by a named query or @Query annotation - @Modifying - void updateMethod(String firstname); - - - // Modifying and Pageable is not allowed - @Modifying - Page updateMethod(String firstname, Pageable pageable); - - - // Modifying and Sort is not allowed - @Modifying - void updateMethod(String firstname, Sort sort); - } + // Modifying and Sort is not allowed + @Modifying + void updateMethod(String firstname, Sort sort); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/NamedQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/NamedQueryUnitTests.java index acffb0d89..a292b1bbf 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/NamedQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/NamedQueryUnitTests.java @@ -31,7 +31,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.QueryCreationException; - /** * Unit tests for {@link NamedQuery}. * @@ -40,37 +39,34 @@ import org.springframework.data.repository.query.QueryCreationException; @RunWith(MockitoJUnitRunner.class) public class NamedQueryUnitTests { - @Mock - RepositoryMetadata metadata; - @Mock - QueryExtractor extractor; - @Mock - EntityManager em; + @Mock + RepositoryMetadata metadata; + @Mock + QueryExtractor extractor; + @Mock + EntityManager em; - Method method; + Method method; + @Before + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void setUp() throws SecurityException, NoSuchMethodException { - @Before - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void setUp() throws SecurityException, NoSuchMethodException { + method = SampleRepository.class.getMethod("foo", Pageable.class); + when(metadata.getDomainClass()).thenReturn((Class) String.class); + } - method = SampleRepository.class.getMethod("foo", Pageable.class); - when(metadata.getDomainClass()).thenReturn((Class) String.class); - } + @Test(expected = QueryCreationException.class) + public void rejectsPersistenceProviderIfIncapableOfExtractingQueriesAndPagebleBeingUsed() { + when(extractor.canExtractQuery()).thenReturn(false); - @Test(expected = QueryCreationException.class) - public void rejectsPersistenceProviderIfIncapableOfExtractingQueriesAndPagebleBeingUsed() { + JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor); + NamedQuery.lookupFrom(queryMethod, em); + } - when(extractor.canExtractQuery()).thenReturn(false); + interface SampleRepository { - JpaQueryMethod queryMethod = - new JpaQueryMethod(method, metadata, extractor); - NamedQuery.lookupFrom(queryMethod, em); - } - - interface SampleRepository { - - Page foo(Pageable pageable); - } + Page foo(Pageable pageable); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java index 0bfa12a10..957068364 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java @@ -35,7 +35,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Parameters; - /** * Unit test for {@link ParameterBinder}. * @@ -44,185 +43,146 @@ import org.springframework.data.repository.query.Parameters; @RunWith(MockitoJUnitRunner.class) public class ParameterBinderUnitTests { - private Method valid; + private Method valid; - @Mock - private Query query; - private Method useIndexedParameters; - private Method indexedParametersWithSort; + @Mock + private Query query; + private Method useIndexedParameters; + private Method indexedParametersWithSort; + @Before + public void setUp() throws SecurityException, NoSuchMethodException { - @Before - public void setUp() throws SecurityException, NoSuchMethodException { + valid = SampleRepository.class.getMethod("valid", String.class); - valid = SampleRepository.class.getMethod("valid", String.class); + useIndexedParameters = SampleRepository.class.getMethod("useIndexedParameters", String.class); + indexedParametersWithSort = SampleRepository.class.getMethod("indexedParameterWithSort", String.class, Sort.class); + } - useIndexedParameters = - SampleRepository.class.getMethod("useIndexedParameters", - String.class); - indexedParametersWithSort = - SampleRepository.class.getMethod("indexedParameterWithSort", - String.class, Sort.class); - } + static class User { - static class User { + } - } + static interface SampleRepository { - static interface SampleRepository { + User useIndexedParameters(String lastname); - User useIndexedParameters(String lastname); + User indexedParameterWithSort(String lastname, Sort sort); + User valid(@Param("username") String username); - User indexedParameterWithSort(String lastname, Sort sort); + User validWithPageable(@Param("username") String username, Pageable pageable); + User validWithSort(@Param("username") String username, Sort sort); + } - User valid(@Param("username") String username); + @Test(expected = IllegalArgumentException.class) + public void rejectsToManyParameters() throws Exception { + new ParameterBinder(new Parameters(valid), new Object[] { "foo", "bar" }); + } - User validWithPageable(@Param("username") String username, - Pageable pageable); + @Test(expected = IllegalArgumentException.class) + public void rejectsNullParameters() throws Exception { + new ParameterBinder(new Parameters(valid), (Object[]) null); + } - User validWithSort(@Param("username") String username, Sort sort); - } + @Test(expected = IllegalArgumentException.class) + public void rejectsToLittleParameters() throws SecurityException, NoSuchMethodException { + Parameters parameters = new Parameters(valid); + new ParameterBinder(parameters); + } - @Test(expected = IllegalArgumentException.class) - public void rejectsToManyParameters() throws Exception { + @Test + public void returnsNullIfNoPageableWasProvided() throws SecurityException, NoSuchMethodException { - new ParameterBinder(new Parameters(valid), - new Object[] { "foo", "bar" }); - } + Method method = SampleRepository.class.getMethod("validWithPageable", String.class, Pageable.class); + Parameters parameters = new Parameters(method); + ParameterBinder binder = new ParameterBinder(parameters, new Object[] { "foo", null }); - @Test(expected = IllegalArgumentException.class) - public void rejectsNullParameters() throws Exception { + assertThat(binder.getPageable(), is(nullValue())); + } - new ParameterBinder(new Parameters(valid), (Object[]) null); - } + @Test + public void bindWorksWithNullForSort() throws Exception { + Method validWithSort = SampleRepository.class.getMethod("validWithSort", String.class, Sort.class); - @Test(expected = IllegalArgumentException.class) - public void rejectsToLittleParameters() throws SecurityException, - NoSuchMethodException { + new ParameterBinder(new Parameters(validWithSort), new Object[] { "foo", null }).bind(query); + verify(query).setParameter(eq(1), eq("foo")); + } - Parameters parameters = new Parameters(valid); - new ParameterBinder(parameters); - } + @Test + public void bindWorksWithNullForPageable() throws Exception { + Method validWithPageable = SampleRepository.class.getMethod("validWithPageable", String.class, Pageable.class); - @Test - public void returnsNullIfNoPageableWasProvided() throws SecurityException, - NoSuchMethodException { + new ParameterBinder(new Parameters(validWithPageable), new Object[] { "foo", null }).bind(query); + verify(query).setParameter(eq(1), eq("foo")); + } - Method method = - SampleRepository.class.getMethod("validWithPageable", - String.class, Pageable.class); + @Test + public void usesIndexedParametersIfNoParamAnnotationPresent() throws Exception { - Parameters parameters = new Parameters(method); - ParameterBinder binder = - new ParameterBinder(parameters, new Object[] { "foo", null }); + new ParameterBinder(new Parameters(useIndexedParameters), new Object[] { "foo" }).bind(query); + verify(query).setParameter(eq(1), anyObject()); + } - assertThat(binder.getPageable(), is(nullValue())); - } + @Test + public void usesParameterNameIfAnnotated() throws Exception { + when(query.setParameter(eq("username"), anyObject())).thenReturn(query); + new ParameterBinder(new Parameters(valid), new Object[] { "foo" }) { - @Test - public void bindWorksWithNullForSort() throws Exception { + @Override + boolean hasNamedParameter(Query query) { - Method validWithSort = - SampleRepository.class.getMethod("validWithSort", String.class, - Sort.class); + return true; + } + }.bind(query); + verify(query).setParameter(eq("username"), anyObject()); + } - new ParameterBinder(new Parameters(validWithSort), new Object[] { - "foo", null }).bind(query); - verify(query).setParameter(eq(1), eq("foo")); - } + @Test + public void bindsEmbeddableCorrectly() throws Exception { + Method method = getClass().getMethod("findByEmbeddable", SampleEmbeddable.class); + Parameters parameters = new Parameters(method); + SampleEmbeddable embeddable = new SampleEmbeddable(); - @Test - public void bindWorksWithNullForPageable() throws Exception { + new ParameterBinder(parameters, new Object[] { embeddable }).bind(query); - Method validWithPageable = - SampleRepository.class.getMethod("validWithPageable", - String.class, Pageable.class); + verify(query).setParameter(1, embeddable); + } - new ParameterBinder(new Parameters(validWithPageable), new Object[] { - "foo", null }).bind(query); - verify(query).setParameter(eq(1), eq("foo")); - } + @Test + public void bindsSortForIndexedParameters() throws Exception { + Sort sort = new Sort("name"); + ParameterBinder binder = new ParameterBinder(new Parameters(indexedParametersWithSort), + new Object[] { "name", sort }); + assertThat(binder.getSort(), is(sort)); + } - @Test - public void usesIndexedParametersIfNoParamAnnotationPresent() - throws Exception { + public SampleEntity findByEmbeddable(SampleEmbeddable embeddable) { - new ParameterBinder(new Parameters(useIndexedParameters), - new Object[] { "foo" }).bind(query); - verify(query).setParameter(eq(1), anyObject()); - } + return null; + } + @SuppressWarnings("unused") + static class SampleEntity { - @Test - public void usesParameterNameIfAnnotated() throws Exception { + private SampleEmbeddable embeddable; + } - when(query.setParameter(eq("username"), anyObject())).thenReturn(query); - new ParameterBinder(new Parameters(valid), new Object[] { "foo" }) { + @Embeddable + @SuppressWarnings("unused") + public static class SampleEmbeddable { - @Override - boolean hasNamedParameter(Query query) { - - return true; - } - }.bind(query); - verify(query).setParameter(eq("username"), anyObject()); - } - - - @Test - public void bindsEmbeddableCorrectly() throws Exception { - - Method method = - getClass() - .getMethod("findByEmbeddable", SampleEmbeddable.class); - Parameters parameters = new Parameters(method); - SampleEmbeddable embeddable = new SampleEmbeddable(); - - new ParameterBinder(parameters, new Object[] { embeddable }) - .bind(query); - - verify(query).setParameter(1, embeddable); - } - - - @Test - public void bindsSortForIndexedParameters() throws Exception { - - Sort sort = new Sort("name"); - ParameterBinder binder = - new ParameterBinder(new Parameters(indexedParametersWithSort), - new Object[] { "name", sort }); - assertThat(binder.getSort(), is(sort)); - } - - - public SampleEntity findByEmbeddable(SampleEmbeddable embeddable) { - - return null; - } - - @SuppressWarnings("unused") - static class SampleEntity { - - private SampleEmbeddable embeddable; - } - - @Embeddable - @SuppressWarnings("unused") - public static class SampleEmbeddable { - - private String foo; - private String bar; - } + private String foo; + private String bar; + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java index 3524d48f0..20963e0b5 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/PartTreeJpaQueryIntegrationTests.java @@ -32,7 +32,6 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - /** * Integration tests for {@link PartTreeJpaQuery}. * @@ -42,33 +41,27 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @ContextConfiguration("classpath:infrastructure.xml") public class PartTreeJpaQueryIntegrationTests { - @PersistenceContext - EntityManager entityManager; + @PersistenceContext + EntityManager entityManager; + /** + * @see DATADOC-90 + * @throws Exception + */ + @Test + public void test() throws Exception { - /** - * @see DATADOC-90 - * @throws Exception - */ - @Test - public void test() throws Exception { + Method method = UserRepository.class.getMethod("findByFirstname", String.class, Pageable.class); + JpaQueryMethod queryMethod = new JpaQueryMethod(method, new DefaultRepositoryMetadata(UserRepository.class), + PersistenceProvider.fromEntityManager(entityManager)); + PartTreeJpaQuery jpaQuery = new PartTreeJpaQuery(queryMethod, entityManager); - Method method = - UserRepository.class.getMethod("findByFirstname", String.class, - Pageable.class); - JpaQueryMethod queryMethod = - new JpaQueryMethod(method, new DefaultRepositoryMetadata( - UserRepository.class), - PersistenceProvider.fromEntityManager(entityManager)); - PartTreeJpaQuery jpaQuery = - new PartTreeJpaQuery(queryMethod, entityManager); + jpaQuery.createQuery(new Object[] { "Matthews", new PageRequest(0, 1) }); + jpaQuery.createQuery(new Object[] { "Matthews", new PageRequest(0, 1) }); + } - jpaQuery.createQuery(new Object[] { "Matthews", new PageRequest(0, 1) }); - jpaQuery.createQuery(new Object[] { "Matthews", new PageRequest(0, 1) }); - } + interface UserRepository extends Repository { - interface UserRepository extends Repository { - - Page findByFirstname(String firstname, Pageable pageable); - } + Page findByFirstname(String firstname, Pageable pageable); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java index 68a25deca..155728fca 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java @@ -22,7 +22,6 @@ import static org.springframework.data.jpa.repository.query.QueryUtils.*; import org.hamcrest.Matcher; import org.junit.Test; - /** * Unit test for {@link QueryUtils}. * @@ -30,129 +29,109 @@ import org.junit.Test; */ public class QueryUtilsUnitTests { - static final String QUERY = "select u from User u"; - static final String FQ_QUERY = - "select u from org.acme.domain.User$Foo_Bar u"; - static final String SIMPLE_QUERY = "from User u"; - static final String COUNT_QUERY = "select count(u) from User u"; + static final String QUERY = "select u from User u"; + static final String FQ_QUERY = "select u from org.acme.domain.User$Foo_Bar u"; + static final String SIMPLE_QUERY = "from User u"; + static final String COUNT_QUERY = "select count(u) from User u"; - static final String QUERY_WITH_AS = - "select u from User as u where u.username = ?"; + static final String QUERY_WITH_AS = "select u from User as u where u.username = ?"; - static final Matcher IS_U = is("u"); + static final Matcher IS_U = is("u"); + @Test + public void createsCountQueryCorrectly() throws Exception { - @Test - public void createsCountQueryCorrectly() throws Exception { + assertCountQuery(QUERY, COUNT_QUERY); - assertCountQuery(QUERY, COUNT_QUERY); + } - } + /** + * @see #303 + */ + @Test + public void createsCountQueriesCorrectlyForCapitalLetterJPQL() { + assertCountQuery("FROM User u WHERE u.foo.bar = ?", "select count(u) FROM User u WHERE u.foo.bar = ?"); - /** - * @see #303 - */ - @Test - public void createsCountQueriesCorrectlyForCapitalLetterJPQL() { + assertCountQuery("SELECT u FROM User u where u.foo.bar = ?", "select count(u) FROM User u where u.foo.bar = ?"); + } - assertCountQuery("FROM User u WHERE u.foo.bar = ?", - "select count(u) FROM User u WHERE u.foo.bar = ?"); + /** + * @see #351 + */ + @Test + public void createsCountQueryForDistinctQueries() throws Exception { - assertCountQuery("SELECT u FROM User u where u.foo.bar = ?", - "select count(u) FROM User u where u.foo.bar = ?"); - } + assertCountQuery("select distinct u from User u where u.foo = ?", + "select count(distinct u) from User u where u.foo = ?"); + } + /** + * @see #351 + */ + @Test + public void createsCountQueryForConstructorQueries() throws Exception { - /** - * @see #351 - */ - @Test - public void createsCountQueryForDistinctQueries() throws Exception { + assertCountQuery("select distinct new User(u.name) from User u where u.foo = ?", + "select count(distinct u) from User u where u.foo = ?"); + } - assertCountQuery("select distinct u from User u where u.foo = ?", - "select count(distinct u) from User u where u.foo = ?"); - } + /** + * @see #352 + */ + @Test + public void createsCountQueryForJoins() throws Exception { + assertCountQuery("select distinct new User(u.name) from User u left outer join u.roles r WHERE r = ?", + "select count(distinct u) from User u left outer join u.roles r WHERE r = ?"); + } - /** - * @see #351 - */ - @Test - public void createsCountQueryForConstructorQueries() throws Exception { + /** + * @see #352 + */ + @Test + public void createsCountQueryForQueriesWithSubSelects() throws Exception { - assertCountQuery( - "select distinct new User(u.name) from User u where u.foo = ?", - "select count(distinct u) from User u where u.foo = ?"); - } + assertCountQuery("select u from User u left outer join u.roles r where r in (select r from Role)", + "select count(u) from User u left outer join u.roles r where r in (select r from Role)"); + } + /** + * @see #355 + */ + @Test + public void createsCountQueryForAliasesCorrectly() throws Exception { - /** - * @see #352 - */ - @Test - public void createsCountQueryForJoins() throws Exception { + assertCountQuery("select u from User as u", "select count(u) from User as u"); + } - assertCountQuery( - "select distinct new User(u.name) from User u left outer join u.roles r WHERE r = ?", - "select count(distinct u) from User u left outer join u.roles r WHERE r = ?"); - } + @Test + public void allowsShortJpaSyntax() throws Exception { + assertCountQuery(SIMPLE_QUERY, COUNT_QUERY); + } - /** - * @see #352 - */ - @Test - public void createsCountQueryForQueriesWithSubSelects() throws Exception { + @Test + public void detectsAliasCorrectly() throws Exception { - assertCountQuery( - "select u from User u left outer join u.roles r where r in (select r from Role)", - "select count(u) from User u left outer join u.roles r where r in (select r from Role)"); - } + assertThat(detectAlias(QUERY), IS_U); + assertThat(detectAlias(SIMPLE_QUERY), IS_U); + assertThat(detectAlias(COUNT_QUERY), IS_U); + assertThat(detectAlias(QUERY_WITH_AS), IS_U); + assertThat(detectAlias("SELECT FROM USER U"), is("U")); + assertThat(detectAlias("select u from User u"), IS_U); + assertThat(detectAlias("select u from com.acme.User u"), IS_U); + } + @Test + public void allowsFullyQualifiedEntityNamesInQuery() { - /** - * @see #355 - */ - @Test - public void createsCountQueryForAliasesCorrectly() throws Exception { + assertThat(detectAlias(FQ_QUERY), IS_U); + assertCountQuery(FQ_QUERY, "select count(u) from org.acme.domain.User$Foo_Bar u"); + } - assertCountQuery("select u from User as u", - "select count(u) from User as u"); - } + private void assertCountQuery(String originalQuery, String countQuery) { - - @Test - public void allowsShortJpaSyntax() throws Exception { - - assertCountQuery(SIMPLE_QUERY, COUNT_QUERY); - } - - - @Test - public void detectsAliasCorrectly() throws Exception { - - assertThat(detectAlias(QUERY), IS_U); - assertThat(detectAlias(SIMPLE_QUERY), IS_U); - assertThat(detectAlias(COUNT_QUERY), IS_U); - assertThat(detectAlias(QUERY_WITH_AS), IS_U); - assertThat(detectAlias("SELECT FROM USER U"), is("U")); - assertThat(detectAlias("select u from User u"), IS_U); - assertThat(detectAlias("select u from com.acme.User u"), IS_U); - } - - - @Test - public void allowsFullyQualifiedEntityNamesInQuery() { - - assertThat(detectAlias(FQ_QUERY), IS_U); - assertCountQuery(FQ_QUERY, - "select count(u) from org.acme.domain.User$Foo_Bar u"); - } - - - private void assertCountQuery(String originalQuery, String countQuery) { - - assertThat(createCountQueryFor(originalQuery), is(countQuery)); - } + assertThat(createCountQueryFor(originalQuery), is(countQuery)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java index 312376df7..87ad4b90c 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java @@ -39,7 +39,6 @@ import org.springframework.data.jpa.repository.sample.UserRepository; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.Parameters; - /** * Unit test for {@link SimpleJpaQuery}. * @@ -48,79 +47,67 @@ import org.springframework.data.repository.query.Parameters; @RunWith(MockitoJUnitRunner.class) public class SimpleJpaQueryUnitTests { - JpaQueryMethod method; + JpaQueryMethod method; - @Mock - EntityManager em; - @Mock - QueryExtractor extractor; - @Mock - Query query; - @Mock - RepositoryMetadata metadata; - @Mock - ParameterBinder binder; + @Mock + EntityManager em; + @Mock + QueryExtractor extractor; + @Mock + Query query; + @Mock + RepositoryMetadata metadata; + @Mock + ParameterBinder binder; + @Before + @QueryHints(@QueryHint(name = "foo", value = "bar")) + public void setUp() throws SecurityException, NoSuchMethodException { - @Before - @QueryHints(@QueryHint(name = "foo", value = "bar")) - public void setUp() throws SecurityException, NoSuchMethodException { + when(em.createQuery(anyString())).thenReturn(query); - when(em.createQuery(anyString())).thenReturn(query); + Method setUp = UserRepository.class.getMethod("findByLastname", String.class); + method = new JpaQueryMethod(setUp, metadata, extractor); + } - Method setUp = - UserRepository.class.getMethod("findByLastname", String.class); - method = new JpaQueryMethod(setUp, metadata, extractor); - } + @Test + public void appliesHintsCorrectly() throws Exception { + SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "foobar"); + jpaQuery.createQuery(new Object[] { "gierke" }); - @Test - public void appliesHintsCorrectly() throws Exception { + verify(query).setHint("foo", "bar"); + } - SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "foobar"); - jpaQuery.createQuery(new Object[] { "gierke" }); + @Test + public void prefersDeclaredCountQueryOverCreatingOne() throws Exception { - verify(query).setHint("foo", "bar"); - } + method = mock(JpaQueryMethod.class); + when(method.getCountQuery()).thenReturn("foo"); + when(method.getParameters()).thenReturn( + new Parameters(SimpleJpaQueryUnitTests.class.getMethod("prefersDeclaredCountQueryOverCreatingOne"))); + when(em.createQuery("foo")).thenReturn(query); + SimpleJpaQuery jpaQuery = new SimpleJpaQuery(method, em, "select u from User u"); - @Test - public void prefersDeclaredCountQueryOverCreatingOne() throws Exception { + assertThat(jpaQuery.createCountQuery(new Object[] {}), is(query)); + } - method = mock(JpaQueryMethod.class); - when(method.getCountQuery()).thenReturn("foo"); - when(method.getParameters()) - .thenReturn( - new Parameters( - SimpleJpaQueryUnitTests.class - .getMethod("prefersDeclaredCountQueryOverCreatingOne"))); - when(em.createQuery("foo")).thenReturn(query); + /** + * @see DATAJPA-77 + */ + @Test + public void doesNotApplyPaginationToCountQuery() throws Exception { - SimpleJpaQuery jpaQuery = - new SimpleJpaQuery(method, em, "select u from User u"); + when(em.createQuery(Mockito.anyString())).thenReturn(query); - assertThat(jpaQuery.createCountQuery(new Object[] {}), is(query)); - } + Method method = UserRepository.class.getMethod("findAllPaged", Pageable.class); + JpaQueryMethod queryMethod = new JpaQueryMethod(method, metadata, extractor); + AbstractJpaQuery jpaQuery = new SimpleJpaQuery(queryMethod, em, "select u from User u"); + jpaQuery.createCountQuery(new Object[] { new PageRequest(1, 10) }); - /** - * @see DATAJPA-77 - */ - @Test - public void doesNotApplyPaginationToCountQuery() throws Exception { - - when(em.createQuery(Mockito.anyString())).thenReturn(query); - - Method method = - UserRepository.class.getMethod("findAllPaged", Pageable.class); - JpaQueryMethod queryMethod = - new JpaQueryMethod(method, metadata, extractor); - - AbstractJpaQuery jpaQuery = - new SimpleJpaQuery(queryMethod, em, "select u from User u"); - jpaQuery.createCountQuery(new Object[] { new PageRequest(1, 10) }); - - verify(query, times(0)).setFirstResult(anyInt()); - verify(query, times(0)).setMaxResults(anyInt()); - } + verify(query, times(0)).setFirstResult(anyInt()); + verify(query, times(0)).setMaxResults(anyInt()); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/AuditableUserRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/AuditableUserRepository.java index 7b06b371e..7a7b91df3 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/AuditableUserRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/AuditableUserRepository.java @@ -20,20 +20,18 @@ import java.util.List; import org.springframework.data.jpa.domain.sample.AuditableUser; import org.springframework.data.jpa.repository.JpaRepository; - /** * Repository interface for {@code AuditableUser}. * * @author Oliver Gierke */ -public interface AuditableUserRepository extends - JpaRepository { +public interface AuditableUserRepository extends JpaRepository { - /** - * Returns all users with the given firstname. - * - * @param firstname - * @return all users with the given firstname. - */ - public List findByFirstname(final String firstname); + /** + * Returns all users with the given firstname. + * + * @param firstname + * @return all users with the given firstname. + */ + public List findByFirstname(final String firstname); } diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/RoleRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/RoleRepository.java index a0ae429dc..e40ab9f25 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/RoleRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/RoleRepository.java @@ -18,7 +18,6 @@ package org.springframework.data.jpa.repository.sample; import org.springframework.data.jpa.domain.sample.Role; import org.springframework.data.repository.CrudRepository; - /** * Typing interface for {@code Role}. * diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java index 49debcd2e..0d04d43c9 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java @@ -34,188 +34,148 @@ import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; - /** * Repository interface for {@code User}s. * * @author Oliver Gierke */ -public interface UserRepository extends JpaRepository, - JpaSpecificationExecutor, UserRepositoryCustom { +public interface UserRepository extends JpaRepository, JpaSpecificationExecutor, + UserRepositoryCustom { - /** - * Retrieve users by their lastname. The finder - * {@literal User.findByLastname} is declared in {@literal META-INF/orm.xml} - * . - * - * @param lastname - * @return all users with the given lastname - */ - @QueryHints({ @QueryHint(name = "foo", value = "bar") }) - List findByLastname(String lastname); + /** + * Retrieve users by their lastname. The finder {@literal User.findByLastname} is declared in + * {@literal META-INF/orm.xml} . + * + * @param lastname + * @return all users with the given lastname + */ + @QueryHints({ @QueryHint(name = "foo", value = "bar") }) + List findByLastname(String lastname); + /** + * Redeclaration of {@link CrudRepository#findOne(java.io.Serializable)} to change transaction configuration. + */ + @Transactional + public User findOne(Integer primaryKey); - /** - * Redeclaration of {@link CrudRepository#findOne(java.io.Serializable)} to - * change transaction configuration. - */ - @Transactional - public User findOne(Integer primaryKey); + /** + * Retrieve users by their email address. The finder {@literal User.findByEmailAddress} is declared as annotation at + * {@code User}. + * + * @param emailAddress + * @return the user with the given email address + */ + User findByEmailAddress(String emailAddress); + @Query("select u from User u ") + Page findAllPaged(Pageable pageable); - /** - * Retrieve users by their email address. The finder - * {@literal User.findByEmailAddress} is declared as annotation at - * {@code User}. - * - * @param emailAddress - * @return the user with the given email address - */ - User findByEmailAddress(String emailAddress); + /** + * Retrieves users by the given email and lastname. Acts as a dummy method declaration to test finder query creation. + * + * @param emailAddress + * @param lastname + * @return the user with the given email address and lastname + */ + User findByEmailAddressAndLastname(String emailAddress, String lastname); + /** + * Retrieves users by email address and lastname or firstname. Acts as a dummy method declaration to test finder query + * creation. + * + * @param emailAddress + * @param lastname + * @param username + * @return the users with the given email address and lastname or the given firstname + */ + List findByEmailAddressAndLastnameOrFirstname(String emailAddress, String lastname, String username); - @Query("select u from User u ") - Page findAllPaged(Pageable pageable); + /** + * Retrieves a user by its username using the query annotated to the method. + * + * @param username + * @return + */ + @Query("select u from User u where u.emailAddress = ?1") + @Transactional(readOnly = true) + User findByAnnotatedQuery(String emailAddress); + /** + * Method to directly create query from and adding a {@link Pageable} parameter to be regarded on query execution. + * + * @param pageable + * @param lastname + * @return + */ + Page findByLastname(Pageable pageable, String lastname); - /** - * Retrieves users by the given email and lastname. Acts as a dummy method - * declaration to test finder query creation. - * - * @param emailAddress - * @param lastname - * @return the user with the given email address and lastname - */ - User findByEmailAddressAndLastname(String emailAddress, String lastname); + /** + * Method to directly create query from and adding a {@link Pageable} parameter to be regarded on query execution. + * Just returns the queried {@link Page}'s contents. + * + * @param firstname + * @param pageable + * @return + */ + List findByFirstname(String firstname, Pageable pageable); + Page findByFirstnameIn(Pageable pageable, String... firstnames); - /** - * Retrieves users by email address and lastname or firstname. Acts as a - * dummy method declaration to test finder query creation. - * - * @param emailAddress - * @param lastname - * @param username - * @return the users with the given email address and lastname or the given - * firstname - */ - List findByEmailAddressAndLastnameOrFirstname(String emailAddress, - String lastname, String username); + List findByFirstnameNotIn(Collection firstnames); + /** + * Manipulating query to set all {@link User}'s names to the given one. + * + * @param lastname + */ + @Modifying + @Query("update User u set u.lastname = ?1") + void renameAllUsersTo(String lastname); - /** - * Retrieves a user by its username using the query annotated to the method. - * - * @param username - * @return - */ - @Query("select u from User u where u.emailAddress = ?1") - @Transactional(readOnly = true) - User findByAnnotatedQuery(String emailAddress); + @Query("select count(u) from User u where u.firstname = ?1") + Long countWithFirstname(String firstname); + /** + * Method where parameters will be applied by name. Note that the order of the parameters is then not crucial anymore. + * + * @param firstname + * @param lastname + * @return + */ + @Query("select u from User u where u.lastname = :lastname or u.firstname = :firstname") + List findByLastnameOrFirstname(@Param("firstname") String foo, @Param("lastname") String bar); - /** - * Method to directly create query from and adding a {@link Pageable} - * parameter to be regarded on query execution. - * - * @param pageable - * @param lastname - * @return - */ - Page findByLastname(Pageable pageable, String lastname); + @Query("select u from User u where u.lastname = :lastname or u.firstname = :firstname") + List findByLastnameOrFirstnameUnannotated(String firstname, String lastname); + /** + * Method to check query creation and named parameter usage go well hand in hand. + * + * @param lastname + * @param firstname + * @return + */ + List findByFirstnameOrLastname(@Param("lastname") String lastname, @Param("firstname") String firstname); - /** - * Method to directly create query from and adding a {@link Pageable} - * parameter to be regarded on query execution. Just returns the queried - * {@link Page}'s contents. - * - * @param firstname - * @param pageable - * @return - */ - List findByFirstname(String firstname, Pageable pageable); + List findByLastnameLikeOrderByFirstnameDesc(String lastname); + List findByLastnameNotLike(String lastname); - Page findByFirstnameIn(Pageable pageable, String... firstnames); + List findByLastnameNot(String lastname); + List findByManagerLastname(String name); - List findByFirstnameNotIn(Collection firstnames); + List findByColleaguesLastname(String lastname); + List findByLastnameNotNull(); - /** - * Manipulating query to set all {@link User}'s names to the given one. - * - * @param lastname - */ - @Modifying - @Query("update User u set u.lastname = ?1") - void renameAllUsersTo(String lastname); + List findByLastnameNull(); + List findByEmailAddressLike(String email, Sort sort); - @Query("select count(u) from User u where u.firstname = ?1") - Long countWithFirstname(String firstname); + List findSpecialUsersByLastname(String lastname); + List findBySpringDataNamedQuery(String lastname); - /** - * Method where parameters will be applied by name. Note that the order of - * the parameters is then not crucial anymore. - * - * @param firstname - * @param lastname - * @return - */ - @Query("select u from User u where u.lastname = :lastname or u.firstname = :firstname") - List findByLastnameOrFirstname(@Param("firstname") String foo, - @Param("lastname") String bar); - - - @Query("select u from User u where u.lastname = :lastname or u.firstname = :firstname") - List findByLastnameOrFirstnameUnannotated(String firstname, - String lastname); - - - /** - * Method to check query creation and named parameter usage go well hand in - * hand. - * - * @param lastname - * @param firstname - * @return - */ - List findByFirstnameOrLastname(@Param("lastname") String lastname, - @Param("firstname") String firstname); - - - List findByLastnameLikeOrderByFirstnameDesc(String lastname); - - - List findByLastnameNotLike(String lastname); - - - List findByLastnameNot(String lastname); - - - List findByManagerLastname(String name); - - - List findByColleaguesLastname(String lastname); - - - List findByLastnameNotNull(); - - - List findByLastnameNull(); - - - List findByEmailAddressLike(String email, Sort sort); - - - List findSpecialUsersByLastname(String lastname); - - - List findBySpringDataNamedQuery(String lastname); - - - Page findByLastnameLike(Pageable pageable, String lastname); + Page findByLastnameLike(Pageable pageable, String lastname); } diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryCustom.java b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryCustom.java index 9de7c19ba..dedd90de8 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryCustom.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryCustom.java @@ -17,7 +17,6 @@ package org.springframework.data.jpa.repository.sample; import org.springframework.data.jpa.domain.sample.User; - /** * Simple interface for custom methods on the repository for {@code User}s. * @@ -25,16 +24,15 @@ import org.springframework.data.jpa.domain.sample.User; */ public interface UserRepositoryCustom { - /** - * Method actually triggering a finder but being overridden. - */ - void findByOverrridingMethod(); + /** + * Method actually triggering a finder but being overridden. + */ + void findByOverrridingMethod(); - - /** - * Some custom method to implement. - * - * @param user - */ - void someCustomMethod(User user); + /** + * Some custom method to implement. + * + * @param user + */ + void someCustomMethod(User user); } diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryImpl.java b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryImpl.java index 39c00e5b6..b6812cceb 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryImpl.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepositoryImpl.java @@ -19,7 +19,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.jpa.domain.sample.User; - /** * Dummy implementation to allow check for invoking a custom implementation. * @@ -27,30 +26,27 @@ import org.springframework.data.jpa.domain.sample.User; */ public class UserRepositoryImpl implements UserRepositoryCustom { - private static final Logger LOG = LoggerFactory - .getLogger(UserRepositoryImpl.class); + private static final Logger LOG = LoggerFactory.getLogger(UserRepositoryImpl.class); + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.sample.UserRepositoryCustom# + * someCustomMethod(org.springframework.data.jpa.domain.sample.User) + */ + public void someCustomMethod(User u) { - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.sample.UserRepositoryCustom# - * someCustomMethod(org.springframework.data.jpa.domain.sample.User) - */ - public void someCustomMethod(User u) { + LOG.debug("Some custom method was invoked!"); + } - LOG.debug("Some custom method was invoked!"); - } + /* + * (non-Javadoc) + * + * @see org.springframework.data.jpa.repository.sample.UserRepositoryCustom# + * findByOverrridingMethod() + */ + public void findByOverrridingMethod() { - - /* - * (non-Javadoc) - * - * @see org.springframework.data.jpa.repository.sample.UserRepositoryCustom# - * findByOverrridingMethod() - */ - public void findByOverrridingMethod() { - - LOG.debug("A method overriding a finder was invoked!"); - } + LOG.debug("A method overriding a finder was invoked!"); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefTests.java b/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefTests.java index 854d4d730..b12945acc 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefTests.java @@ -28,10 +28,8 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; - /** - * Assures the injected repository instances are wired to the customly - * configured {@link EntityManagerFactory}. + * Assures the injected repository instances are wired to the customly configured {@link EntityManagerFactory}. * * @author Oliver Gierke */ @@ -39,26 +37,23 @@ import org.springframework.transaction.annotation.Transactional; @ContextConfiguration(locations = "classpath:multiple-entity-manager-integration-context.xml") public class EntityManagerFactoryRefTests { - @Autowired - UserRepository userRepository; + @Autowired + UserRepository userRepository; - @Autowired - AuditableUserRepository auditableUserRepository; + @Autowired + AuditableUserRepository auditableUserRepository; + @Test + @Transactional + public void useUserRepository() throws Exception { - @Test - @Transactional - public void useUserRepository() throws Exception { + userRepository.saveAndFlush(new User("firstname", "lastname", "foo@bar.de")); + } - userRepository.saveAndFlush(new User("firstname", "lastname", - "foo@bar.de")); - } + @Test + @Transactional("transactionManager-2") + public void useAuditableUserRepository() throws Exception { - - @Test - @Transactional("transactionManager-2") - public void useAuditableUserRepository() throws Exception { - - auditableUserRepository.saveAndFlush(new AuditableUser()); - } + auditableUserRepository.saveAndFlush(new AuditableUser()); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefUnitTests.java index 8a1a7219d..52be21df3 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/EntityManagerFactoryRefUnitTests.java @@ -26,47 +26,36 @@ import org.springframework.beans.factory.config.BeanReference; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; - /** - * Assures the injected repository instances are wired to the customly - * configured {@link EntityManagerFactory}. + * Assures the injected repository instances are wired to the customly configured {@link EntityManagerFactory}. * * @author Oliver Gierke */ public class EntityManagerFactoryRefUnitTests { - @Test - public void repositoriesGetTheSecondEntityManagerFactoryInjected2() { + @Test + public void repositoriesGetTheSecondEntityManagerFactoryInjected2() { - XmlBeanFactory factory = - new XmlBeanFactory(new ClassPathResource( - "multiple-entity-manager-context.xml")); + XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("multiple-entity-manager-context.xml")); - BeanDefinition bean = factory.getBeanDefinition("userRepository"); - Object value = getPropertyValue(bean, "entityManager"); - assertTrue(value instanceof BeanDefinition); - BeanDefinition emCreator = (BeanDefinition) value; + BeanDefinition bean = factory.getBeanDefinition("userRepository"); + Object value = getPropertyValue(bean, "entityManager"); + assertTrue(value instanceof BeanDefinition); + BeanDefinition emCreator = (BeanDefinition) value; - BeanReference reference = getConstructorBeanReference(emCreator, 0); - assertThat(reference.getBeanName(), is("secondEntityManagerFactory")); - } + BeanReference reference = getConstructorBeanReference(emCreator, 0); + assertThat(reference.getBeanName(), is("secondEntityManagerFactory")); + } + private Object getPropertyValue(BeanDefinition definition, String propertyName) { - private Object getPropertyValue(BeanDefinition definition, - String propertyName) { + return definition.getPropertyValues().getPropertyValue(propertyName).getValue(); + } - return definition.getPropertyValues().getPropertyValue(propertyName) - .getValue(); - } + private BeanReference getConstructorBeanReference(BeanDefinition definition, int index) { - - private BeanReference getConstructorBeanReference( - BeanDefinition definition, int index) { - - Object value = - definition.getConstructorArgumentValues() - .getIndexedArgumentValues().get(index).getValue(); - assertTrue(value instanceof BeanReference); - return (BeanReference) value; - } + Object value = definition.getConstructorArgumentValues().getIndexedArgumentValues().get(index).getValue(); + assertTrue(value instanceof BeanReference); + return (BeanReference) value; + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupportUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupportUnitTests.java index becaf314e..fd474dc13 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupportUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/JpaEntityInformationSupportUnitTests.java @@ -26,7 +26,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; - /** * Unit tests for {@link AbstractJpaEntityInformation}. * @@ -35,52 +34,45 @@ import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class JpaEntityInformationSupportUnitTests { - @Test - public void usesSimpleClassNameIfNoEntityNameGiven() throws Exception { + @Test + public void usesSimpleClassNameIfNoEntityNameGiven() throws Exception { - JpaEntityInformation information = - new DummyJpaEntityInformation(User.class); - assertEquals("User", information.getEntityName()); + JpaEntityInformation information = new DummyJpaEntityInformation(User.class); + assertEquals("User", information.getEntityName()); - JpaEntityInformation second = - new DummyJpaEntityInformation( - NamedUser.class); - assertEquals("AnotherNamedUser", second.getEntityName()); - } + JpaEntityInformation second = new DummyJpaEntityInformation(NamedUser.class); + assertEquals("AnotherNamedUser", second.getEntityName()); + } - static class User { + static class User { - } + } - @Entity(name = "AnotherNamedUser") - public class NamedUser { + @Entity(name = "AnotherNamedUser") + public class NamedUser { - } + } - static class DummyJpaEntityInformation extends - JpaEntityInformationSupport { + static class DummyJpaEntityInformation extends JpaEntityInformationSupport { - public DummyJpaEntityInformation(Class domainClass) { + public DummyJpaEntityInformation(Class domainClass) { - super(domainClass); - } + super(domainClass); + } + public SingularAttribute getIdAttribute() { - public SingularAttribute getIdAttribute() { + return null; + } - return null; - } + public ID getId(T entity) { + return null; + } - public ID getId(T entity) { + public Class getIdType() { - return null; - } - - - public Class getIdType() { - - return null; - } - } + return null; + } + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformationUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformationUnitTests.java index 884d17402..ad694a515 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformationUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/JpaPersistableEntityInformationUnitTests.java @@ -31,7 +31,6 @@ import org.mockito.runners.MockitoJUnitRunner; import org.springframework.data.domain.Persistable; import org.springframework.data.repository.core.EntityInformation; - /** * Unit tests for {@link JpaPersistableEntityInformation}. * @@ -40,57 +39,52 @@ import org.springframework.data.repository.core.EntityInformation; @RunWith(MockitoJUnitRunner.class) public class JpaPersistableEntityInformationUnitTests { - @Mock - Metamodel metamodel; + @Mock + Metamodel metamodel; - @Mock - EntityType type; + @Mock + EntityType type; - @Mock - @SuppressWarnings("rawtypes") - Type idType; + @Mock + @SuppressWarnings("rawtypes") + Type idType; + @Before + @SuppressWarnings("unchecked") + public void setUp() { - @Before - @SuppressWarnings("unchecked") - public void setUp() { + when(metamodel.entity(Foo.class)).thenReturn(type); + when(type.getIdType()).thenReturn(idType); + } - when(metamodel.entity(Foo.class)).thenReturn(type); - when(type.getIdType()).thenReturn(idType); - } + @Test + public void usesPersistableMethodsForIsNewAndGetId() { + EntityInformation entityInformation = new JpaPersistableEntityInformation(Foo.class, + metamodel); - @Test - public void usesPersistableMethodsForIsNewAndGetId() { + Foo foo = new Foo(); + assertThat(entityInformation.isNew(foo), is(false)); + assertThat(entityInformation.getId(foo), is(nullValue())); - EntityInformation entityInformation = - new JpaPersistableEntityInformation(Foo.class, - metamodel); + foo.id = 1L; + assertThat(entityInformation.isNew(foo), is(true)); + assertThat(entityInformation.getId(foo), is(1L)); + } - Foo foo = new Foo(); - assertThat(entityInformation.isNew(foo), is(false)); - assertThat(entityInformation.getId(foo), is(nullValue())); + @SuppressWarnings("serial") + class Foo implements Persistable { - foo.id = 1L; - assertThat(entityInformation.isNew(foo), is(true)); - assertThat(entityInformation.getId(foo), is(1L)); - } + Long id; - @SuppressWarnings("serial") - class Foo implements Persistable { + public Long getId() { - Long id; + return id; + } + public boolean isNew() { - public Long getId() { - - return id; - } - - - public boolean isNew() { - - return id != null; - } - } + return id != null; + } + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBeanUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBeanUnitTests.java index 59ad31ff7..56db715b9 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBeanUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryBeanUnitTests.java @@ -38,131 +38,114 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactorySupport; - /** * Unit test for {@code JpaRepositoryFactoryBean}. *

- * TODO: Check if test methods double the ones in - * {@link JpaRepositoryFactoryUnitTests}. + * TODO: Check if test methods double the ones in {@link JpaRepositoryFactoryUnitTests}. * * @author Oliver Gierke */ @RunWith(MockitoJUnitRunner.class) public class JpaRepositoryFactoryBeanUnitTests { - JpaRepositoryFactoryBean factoryBean; + JpaRepositoryFactoryBean factoryBean; - @Mock - EntityManager entityManager; - @Mock - RepositoryFactorySupport factory; - @Mock - ListableBeanFactory beanFactory; - @Mock - PersistenceExceptionTranslator translator; - @Mock - Repository repository; + @Mock + EntityManager entityManager; + @Mock + RepositoryFactorySupport factory; + @Mock + ListableBeanFactory beanFactory; + @Mock + PersistenceExceptionTranslator translator; + @Mock + Repository repository; + @Before + @SuppressWarnings("unchecked") + public void setUp() { - @Before - @SuppressWarnings("unchecked") - public void setUp() { + Map beans = new HashMap(); + beans.put("foo", translator); + when(beanFactory.getBeansOfType(eq(PersistenceExceptionTranslator.class), anyBoolean(), anyBoolean())).thenReturn( + beans); + when(factory.getRepository(any(Class.class), any(Object.class))).thenReturn(repository); - Map beans = - new HashMap(); - beans.put("foo", translator); - when( - beanFactory.getBeansOfType( - eq(PersistenceExceptionTranslator.class), anyBoolean(), - anyBoolean())).thenReturn(beans); - when(factory.getRepository(any(Class.class), any(Object.class))) - .thenReturn(repository); + // Setup standard factory configuration + factoryBean = new DummyJpaRepositoryFactoryBean(); + factoryBean.setRepositoryInterface(SimpleSampleRepository.class); + factoryBean.setEntityManager(entityManager); + } - // Setup standard factory configuration - factoryBean = - new DummyJpaRepositoryFactoryBean(); - factoryBean.setRepositoryInterface(SimpleSampleRepository.class); - factoryBean.setEntityManager(entityManager); - } + /** + * Assert that the instance created for the standard configuration is a valid {@code UserRepository}. + * + * @throws Exception + */ + @Test + public void setsUpBasicInstanceCorrectly() throws Exception { + factoryBean.setBeanFactory(beanFactory); + factoryBean.afterPropertiesSet(); - /** - * Assert that the instance created for the standard configuration is a - * valid {@code UserRepository}. - * - * @throws Exception - */ - @Test - public void setsUpBasicInstanceCorrectly() throws Exception { + assertNotNull(factoryBean.getObject()); + } - factoryBean.setBeanFactory(beanFactory); - factoryBean.afterPropertiesSet(); + @Test(expected = IllegalArgumentException.class) + public void requiresListableBeanFactory() throws Exception { - assertNotNull(factoryBean.getObject()); - } + factoryBean.setBeanFactory(mock(BeanFactory.class)); + } + /** + * Assert that the factory rejects calls to {@code JpaRepositoryFactoryBean#setRepositoryInterface(Class)} with + * {@literal null} or any other parameter instance not implementing {@code Repository}. + */ + @Test(expected = IllegalArgumentException.class) + public void preventsNullRepositoryInterface() { - @Test(expected = IllegalArgumentException.class) - public void requiresListableBeanFactory() throws Exception { + factoryBean.setRepositoryInterface(null); + } - factoryBean.setBeanFactory(mock(BeanFactory.class)); - } + /** + * Assert that the factory detects unset repository class and interface in + * {@code JpaRepositoryFactoryBean#afterPropertiesSet()}. + */ + @Test(expected = IllegalArgumentException.class) + public void preventsUnsetRepositoryInterface() throws Exception { + factoryBean = new JpaRepositoryFactoryBean(); + factoryBean.afterPropertiesSet(); + } - /** - * Assert that the factory rejects calls to - * {@code JpaRepositoryFactoryBean#setRepositoryInterface(Class)} with - * {@literal null} or any other parameter instance not implementing - * {@code Repository}. - */ - @Test(expected = IllegalArgumentException.class) - public void preventsNullRepositoryInterface() { + private class DummyJpaRepositoryFactoryBean, S, ID extends Serializable> extends + JpaRepositoryFactoryBean { - factoryBean.setRepositoryInterface(null); - } + /* + * (non-Javadoc) + * + * @see + * org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean + * #createRepositoryFactory() + */ + @Override + protected RepositoryFactorySupport doCreateRepositoryFactory() { + return factory; + } + } - /** - * Assert that the factory detects unset repository class and interface in - * {@code JpaRepositoryFactoryBean#afterPropertiesSet()}. - */ - @Test(expected = IllegalArgumentException.class) - public void preventsUnsetRepositoryInterface() throws Exception { + private interface SimpleSampleRepository extends JpaRepository { - factoryBean = - new JpaRepositoryFactoryBean(); - factoryBean.afterPropertiesSet(); - } + } - private class DummyJpaRepositoryFactoryBean, S, ID extends Serializable> - extends JpaRepositoryFactoryBean { + /** + * Helper class to make the factory use {@link PersistableMetadata} . + * + * @author Oliver Gierke + */ + @SuppressWarnings("serial") + private static abstract class User implements Persistable { - /* - * (non-Javadoc) - * - * @see - * org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean - * #createRepositoryFactory() - */ - @Override - protected RepositoryFactorySupport doCreateRepositoryFactory() { - - return factory; - } - } - - private interface SimpleSampleRepository extends - JpaRepository { - - } - - /** - * Helper class to make the factory use {@link PersistableMetadata} . - * - * @author Oliver Gierke - */ - @SuppressWarnings("serial") - private static abstract class User implements Persistable { - - } + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryUnitTests.java index 41ac475c0..360536979 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryUnitTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.jpa.repository.support; +import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; import static org.mockito.Mockito.*; -import static org.hamcrest.CoreMatchers.*; import java.io.IOException; import java.io.Serializable; @@ -38,7 +38,6 @@ import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.transaction.annotation.Transactional; - /** * Unit test for {@code JpaRepositoryFactory}. * @@ -47,177 +46,146 @@ import org.springframework.transaction.annotation.Transactional; @RunWith(MockitoJUnitRunner.class) public class JpaRepositoryFactoryUnitTests { - JpaRepositoryFactory factory; + JpaRepositoryFactory factory; - @Mock - EntityManager entityManager; - @Mock - @SuppressWarnings("rawtypes") - JpaEntityInformation metadata; + @Mock + EntityManager entityManager; + @Mock + @SuppressWarnings("rawtypes") + JpaEntityInformation metadata; + @Before + public void setUp() { - @Before - public void setUp() { + // Setup standard factory configuration + factory = new JpaRepositoryFactory(entityManager) { - // Setup standard factory configuration - factory = new JpaRepositoryFactory(entityManager) { + @Override + @SuppressWarnings("unchecked") + public JpaEntityInformation getEntityInformation(Class domainClass) { - @Override - @SuppressWarnings("unchecked") - public JpaEntityInformation getEntityInformation( - Class domainClass) { + return metadata; + }; + }; + } - return metadata; - }; - }; - } + /** + * Assert that the instance created for the standard configuration is a valid {@code UserRepository}. + * + * @throws Exception + */ + @Test + public void setsUpBasicInstanceCorrectly() throws Exception { + assertNotNull(factory.getRepository(SimpleSampleRepository.class)); + } - /** - * Assert that the instance created for the standard configuration is a - * valid {@code UserRepository}. - * - * @throws Exception - */ - @Test - public void setsUpBasicInstanceCorrectly() throws Exception { + @Test + public void allowsCallingOfObjectMethods() { - assertNotNull(factory.getRepository(SimpleSampleRepository.class)); - } + SimpleSampleRepository repository = factory.getRepository(SimpleSampleRepository.class); + repository.hashCode(); + repository.toString(); + repository.equals(repository); + } - @Test - public void allowsCallingOfObjectMethods() { + /** + * Asserts that the factory recognized configured repository classes that contain custom method but no custom + * implementation could be found. Furthremore the exception has to contain the name of the repository interface as for + * a large repository configuration it's hard to find out where this error occured. + * + * @throws Exception + */ + @Test + public void capturesMissingCustomImplementationAndProvidesInterfacename() throws Exception { - SimpleSampleRepository repository = - factory.getRepository(SimpleSampleRepository.class); + try { + factory.getRepository(SampleRepository.class); + } catch (IllegalArgumentException e) { + assertTrue(e.getMessage().contains(SampleRepository.class.getName())); + } + } - repository.hashCode(); - repository.toString(); - repository.equals(repository); - } + @Test(expected = IllegalArgumentException.class) + public void handlesRuntimeExceptionsCorrectly() { + SampleRepository repository = factory.getRepository(SampleRepository.class, new SampleCustomRepositoryImpl()); + repository.throwingRuntimeException(); + } - /** - * Asserts that the factory recognized configured repository classes that - * contain custom method but no custom implementation could be found. - * Furthremore the exception has to contain the name of the repository - * interface as for a large repository configuration it's hard to find out - * where this error occured. - * - * @throws Exception - */ - @Test - public void capturesMissingCustomImplementationAndProvidesInterfacename() - throws Exception { + @Test(expected = IOException.class) + public void handlesCheckedExceptionsCorrectly() throws Exception { - try { - factory.getRepository(SampleRepository.class); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage() - .contains(SampleRepository.class.getName())); - } - } + SampleRepository repository = factory.getRepository(SampleRepository.class, new SampleCustomRepositoryImpl()); + repository.throwingCheckedException(); + } + @Test(expected = UnsupportedOperationException.class) + public void createsProxyWithCustomBaseClass() { - @Test(expected = IllegalArgumentException.class) - public void handlesRuntimeExceptionsCorrectly() { + JpaRepositoryFactory factory = new CustomGenericJpaRepositoryFactory(entityManager); + UserCustomExtendedRepository repository = factory.getRepository(UserCustomExtendedRepository.class); - SampleRepository repository = - factory.getRepository(SampleRepository.class, - new SampleCustomRepositoryImpl()); - repository.throwingRuntimeException(); - } + repository.customMethod(1); + } + @Test + public void usesQueryDslRepositoryIfInterfaceImplementsExecutor() { - @Test(expected = IOException.class) - public void handlesCheckedExceptionsCorrectly() throws Exception { + when(metadata.getJavaType()).thenReturn(User.class); + assertEquals(QueryDslJpaRepository.class, + factory.getRepositoryBaseClass(new DefaultRepositoryMetadata(QueryDslSampleRepository.class))); - SampleRepository repository = - factory.getRepository(SampleRepository.class, - new SampleCustomRepositoryImpl()); - repository.throwingCheckedException(); - } + try { + QueryDslSampleRepository repository = factory.getRepository(QueryDslSampleRepository.class); + assertEquals(QueryDslJpaRepository.class, ((Advised) repository).getTargetClass()); + } catch (IllegalArgumentException e) { + assertThat(e.getStackTrace()[0].getClassName(), is("org.springframework.data.querydsl.SimpleEntityPathResolver")); + } + } + private interface SimpleSampleRepository extends JpaRepository { - @Test(expected = UnsupportedOperationException.class) - public void createsProxyWithCustomBaseClass() { + @Transactional + User findOne(Integer id); + } - JpaRepositoryFactory factory = - new CustomGenericJpaRepositoryFactory(entityManager); - UserCustomExtendedRepository repository = - factory.getRepository(UserCustomExtendedRepository.class); + /** + * Sample interface to contain a custom method. + * + * @author Oliver Gierke + */ + public interface SampleCustomRepository { - repository.customMethod(1); - } + void throwingRuntimeException(); + void throwingCheckedException() throws IOException; + } - @Test - public void usesQueryDslRepositoryIfInterfaceImplementsExecutor() { + /** + * Implementation of the custom repository interface. + * + * @author Oliver Gierke + */ + private class SampleCustomRepositoryImpl implements SampleCustomRepository { - when(metadata.getJavaType()).thenReturn(User.class); - assertEquals(QueryDslJpaRepository.class, - factory.getRepositoryBaseClass(new DefaultRepositoryMetadata( - QueryDslSampleRepository.class))); + public void throwingRuntimeException() { - try { - QueryDslSampleRepository repository = - factory.getRepository(QueryDslSampleRepository.class); - assertEquals(QueryDslJpaRepository.class, - ((Advised) repository).getTargetClass()); - } catch (IllegalArgumentException e) { - assertThat( - e.getStackTrace()[0].getClassName(), - is("org.springframework.data.querydsl.SimpleEntityPathResolver")); - } - } + throw new IllegalArgumentException("You lose!"); + } - private interface SimpleSampleRepository extends - JpaRepository { + public void throwingCheckedException() throws IOException { - @Transactional - User findOne(Integer id); - } + throw new IOException("You lose!"); + } + } - /** - * Sample interface to contain a custom method. - * - * @author Oliver Gierke - */ - public interface SampleCustomRepository { + private interface SampleRepository extends JpaRepository, SampleCustomRepository { - void throwingRuntimeException(); + } + private interface QueryDslSampleRepository extends SimpleSampleRepository, QueryDslPredicateExecutor { - void throwingCheckedException() throws IOException; - } - - /** - * Implementation of the custom repository interface. - * - * @author Oliver Gierke - */ - private class SampleCustomRepositoryImpl implements SampleCustomRepository { - - public void throwingRuntimeException() { - - throw new IllegalArgumentException("You lose!"); - } - - - public void throwingCheckedException() throws IOException { - - throw new IOException("You lose!"); - } - } - - private interface SampleRepository extends JpaRepository, - SampleCustomRepository { - - } - - private interface QueryDslSampleRepository extends SimpleSampleRepository, - QueryDslPredicateExecutor { - - } + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java index 3f657e6d9..619f5355c 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryTests.java @@ -33,7 +33,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; - /** * Integration test for {@link JpaRepository}. * @@ -44,37 +43,31 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class JpaRepositoryTests { - @PersistenceContext - EntityManager em; + @PersistenceContext + EntityManager em; - JpaRepository repository; + JpaRepository repository; + @Before + public void setUp() { - @Before - public void setUp() { + repository = new JpaRepositoryFactory(em).getRepository(SampleEntityRepository.class); + } - repository = - new JpaRepositoryFactory(em) - .getRepository(SampleEntityRepository.class); - } + @Test + public void testCrudOperationsForCompoundKeyEntity() throws Exception { + SampleEntity entity = new SampleEntity("foo", "bar"); + repository.saveAndFlush(entity); + assertThat(repository.count(), is(1L)); + assertThat(repository.findOne(new SampleEntityPK("foo", "bar")), is(entity)); - @Test - public void testCrudOperationsForCompoundKeyEntity() throws Exception { + repository.delete(Arrays.asList(entity)); + repository.flush(); + assertThat(repository.count(), is(0L)); + } - SampleEntity entity = new SampleEntity("foo", "bar"); - repository.saveAndFlush(entity); - assertThat(repository.count(), is(1L)); - assertThat(repository.findOne(new SampleEntityPK("foo", "bar")), - is(entity)); + private static interface SampleEntityRepository extends JpaRepository { - repository.delete(Arrays.asList(entity)); - repository.flush(); - assertThat(repository.count(), is(0L)); - } - - private static interface SampleEntityRepository extends - JpaRepository { - - } + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/QSimpleEntityPathResolverUnitTests_Sample.java b/src/test/java/org/springframework/data/jpa/repository/support/QSimpleEntityPathResolverUnitTests_Sample.java index f5a4458f7..6be28dccb 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/QSimpleEntityPathResolverUnitTests_Sample.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/QSimpleEntityPathResolverUnitTests_Sample.java @@ -22,5 +22,5 @@ package org.springframework.data.jpa.repository.support; */ class QSimpleEntityPathResolverUnitTests_Sample { - public QSimpleEntityPathResolverUnitTests_Sample field; + public QSimpleEntityPathResolverUnitTests_Sample field; } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepositoryTests.java index 188981fe4..b0e5bfb16 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/QueryDslJpaRepositoryTests.java @@ -36,7 +36,6 @@ import com.mysema.query.types.expr.BooleanExpression; import com.mysema.query.types.path.PathBuilder; import com.mysema.query.types.path.PathBuilderFactory; - /** * Integration test for {@link QueryDslJpaRepository}. * @@ -47,57 +46,47 @@ import com.mysema.query.types.path.PathBuilderFactory; @Transactional public class QueryDslJpaRepositoryTests { - @PersistenceContext - EntityManager em; + @PersistenceContext + EntityManager em; - QueryDslJpaRepository repository; - QUser user = new QUser("user"); - User dave, carter; + QueryDslJpaRepository repository; + QUser user = new QUser("user"); + User dave, carter; + @Before + public void setUp() { - @Before - public void setUp() { + JpaEntityInformation information = new JpaMetamodelEntityInformation(User.class, + em.getMetamodel()); - JpaEntityInformation information = - new JpaMetamodelEntityInformation(User.class, - em.getMetamodel()); + repository = new QueryDslJpaRepository(information, em); + dave = repository.save(new User("Dave", "Matthews", "dave@matthews.com")); + carter = repository.save(new User("Carter", "Beauford", "carter@beauford.com")); + } - repository = new QueryDslJpaRepository(information, em); - dave = - repository.save(new User("Dave", "Matthews", - "dave@matthews.com")); - carter = - repository.save(new User("Carter", "Beauford", - "carter@beauford.com")); - } + @Test + public void executesPredicatesCorrectly() throws Exception { + BooleanExpression isCalledDave = user.firstname.eq("Dave"); + BooleanExpression isBeauford = user.lastname.eq("Beauford"); - @Test - public void executesPredicatesCorrectly() throws Exception { + List result = repository.findAll(isCalledDave.or(isBeauford)); - BooleanExpression isCalledDave = user.firstname.eq("Dave"); - BooleanExpression isBeauford = user.lastname.eq("Beauford"); + assertThat(result.size(), is(2)); + assertThat(result, hasItems(carter, dave)); + } - List result = repository.findAll(isCalledDave.or(isBeauford)); + @Test + public void executesStringBasedPredicatesCorrectly() throws Exception { - assertThat(result.size(), is(2)); - assertThat(result, hasItems(carter, dave)); - } + PathBuilder builder = new PathBuilderFactory().create(User.class); + BooleanExpression isCalledDave = builder.getString("firstname").eq("Dave"); + BooleanExpression isBeauford = builder.getString("lastname").eq("Beauford"); - @Test - public void executesStringBasedPredicatesCorrectly() throws Exception { + List result = repository.findAll(isCalledDave.or(isBeauford)); - PathBuilder builder = new PathBuilderFactory().create(User.class); - - BooleanExpression isCalledDave = - builder.getString("firstname").eq("Dave"); - BooleanExpression isBeauford = - builder.getString("lastname").eq("Beauford"); - - List result = repository.findAll(isCalledDave.or(isBeauford)); - - assertThat(result.size(), is(2)); - assertThat(result, hasItems(carter, dave)); - } + assertThat(result.size(), is(2)); + assertThat(result, hasItems(carter, dave)); + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupportTests.java b/src/test/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupportTests.java index 402232994..ef88bdc2e 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupportTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/QueryDslRepositorySupportTests.java @@ -17,7 +17,6 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.transaction.annotation.Transactional; - /** * Integration test for {@link QueryDslRepositorySupport}. * @@ -28,115 +27,104 @@ import org.springframework.transaction.annotation.Transactional; @Transactional public class QueryDslRepositorySupportTests { - @PersistenceContext - EntityManager em; + @PersistenceContext + EntityManager em; - UserRepository repository; - User dave, carter; + UserRepository repository; + User dave, carter; + @Before + public void setup() { - @Before - public void setup() { + dave = new User("Dave", "Matthews", "dave@matthews.com"); + em.persist(dave); - dave = new User("Dave", "Matthews", "dave@matthews.com"); - em.persist(dave); + carter = new User("Carter", "Beauford", "carter@beauford.com"); + em.persist(carter); - carter = new User("Carter", "Beauford", "carter@beauford.com"); - em.persist(carter); + UserRepositoryImpl repository = new UserRepositoryImpl(); + repository.setEntityManager(em); + repository.validate(); - UserRepositoryImpl repository = new UserRepositoryImpl(); - repository.setEntityManager(em); - repository.validate(); + this.repository = repository; + } - this.repository = repository; - } + @Test + public void readsUsersCorrectly() throws Exception { + List result = repository.findUsersByLastname("Matthews"); + assertThat(result.size(), is(1)); + assertThat(result.get(0), is(dave)); - @Test - public void readsUsersCorrectly() throws Exception { + result = repository.findUsersByLastname("Beauford"); + assertThat(result.size(), is(1)); + assertThat(result.get(0), is(carter)); + } - List result = repository.findUsersByLastname("Matthews"); - assertThat(result.size(), is(1)); - assertThat(result.get(0), is(dave)); + @Test + public void updatesUsersCorrectly() throws Exception { - result = repository.findUsersByLastname("Beauford"); - assertThat(result.size(), is(1)); - assertThat(result.get(0), is(carter)); - } + long updates = repository.updateLastnamesTo("Foo"); + assertThat(updates, is(2L)); + List result = repository.findUsersByLastname("Matthews"); + assertThat(result.size(), is(0)); - @Test - public void updatesUsersCorrectly() throws Exception { + result = repository.findUsersByLastname("Beauford"); + assertThat(result.size(), is(0)); - long updates = repository.updateLastnamesTo("Foo"); - assertThat(updates, is(2L)); + result = repository.findUsersByLastname("Foo"); + assertThat(result.size(), is(2)); + assertThat(result, hasItems(dave, carter)); + } - List result = repository.findUsersByLastname("Matthews"); - assertThat(result.size(), is(0)); + @Test + public void deletesAllWithLastnameCorrectly() throws Exception { - result = repository.findUsersByLastname("Beauford"); - assertThat(result.size(), is(0)); + long updates = repository.deleteAllWithLastname("Matthews"); + assertThat(updates, is(1L)); - result = repository.findUsersByLastname("Foo"); - assertThat(result.size(), is(2)); - assertThat(result, hasItems(dave, carter)); - } + List result = repository.findUsersByLastname("Matthews"); + assertThat(result.size(), is(0)); + result = repository.findUsersByLastname("Beauford"); + assertThat(result.size(), is(1)); + assertThat(result.get(0), is(carter)); + } - @Test - public void deletesAllWithLastnameCorrectly() throws Exception { + @Test(expected = IllegalArgumentException.class) + public void rejectsUnsetEntityManager() throws Exception { - long updates = repository.deleteAllWithLastname("Matthews"); - assertThat(updates, is(1L)); + UserRepositoryImpl repositoryImpl = new UserRepositoryImpl(); + repositoryImpl.validate(); + } - List result = repository.findUsersByLastname("Matthews"); - assertThat(result.size(), is(0)); + private static interface UserRepository { - result = repository.findUsersByLastname("Beauford"); - assertThat(result.size(), is(1)); - assertThat(result.get(0), is(carter)); - } + List findUsersByLastname(String firstname); + long updateLastnamesTo(String lastname); - @Test(expected = IllegalArgumentException.class) - public void rejectsUnsetEntityManager() throws Exception { + long deleteAllWithLastname(String lastname); + } - UserRepositoryImpl repositoryImpl = new UserRepositoryImpl(); - repositoryImpl.validate(); - } + private static class UserRepositoryImpl extends QueryDslRepositorySupport implements UserRepository { - private static interface UserRepository { + private static final QUser user = QUser.user; - List findUsersByLastname(String firstname); + public List findUsersByLastname(String lastname) { + return from(user).where(user.lastname.eq(lastname)).list(user); + } - long updateLastnamesTo(String lastname); + public long updateLastnamesTo(String lastname) { + return update(user).set(user.lastname, lastname).execute(); + } - long deleteAllWithLastname(String lastname); - } + public long deleteAllWithLastname(String lastname) { - private static class UserRepositoryImpl extends QueryDslRepositorySupport - implements UserRepository { - - private static final QUser user = QUser.user; - - - public List findUsersByLastname(String lastname) { - - return from(user).where(user.lastname.eq(lastname)).list(user); - } - - - public long updateLastnamesTo(String lastname) { - - return update(user).set(user.lastname, lastname).execute(); - } - - - public long deleteAllWithLastname(String lastname) { - - return delete(user).where(user.lastname.eq(lastname)).execute(); - } - } + return delete(user).where(user.lastname.eq(lastname)).execute(); + } + } } diff --git a/src/test/java/org/springframework/data/jpa/repository/support/TransactionalRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/support/TransactionalRepositoryTests.java index 6fae1d4d5..d1cd052dd 100644 --- a/src/test/java/org/springframework/data/jpa/repository/support/TransactionalRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/support/TransactionalRepositoryTests.java @@ -31,123 +31,103 @@ import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionStatus; - /** * Integration test for transactional behaviour of repository operations. * * @author Oliver Gierke */ -@ContextConfiguration({ "classpath:config/namespace-autoconfig-context.xml", - "classpath:tx-manager.xml" }) -public class TransactionalRepositoryTests extends - AbstractJUnit4SpringContextTests { +@ContextConfiguration({ "classpath:config/namespace-autoconfig-context.xml", "classpath:tx-manager.xml" }) +public class TransactionalRepositoryTests extends AbstractJUnit4SpringContextTests { - @Autowired - UserRepository repository; + @Autowired + UserRepository repository; - @Autowired - DelegatingTransactionManager transactionManager; + @Autowired + DelegatingTransactionManager transactionManager; + @Before + public void setUp() { - @Before - public void setUp() { + transactionManager.resetCount(); + } - transactionManager.resetCount(); - } + @After + public void tearDown() { + repository.deleteAll(); + } - @After - public void tearDown() { + @Test + public void simpleManipulatingOperation() throws Exception { - repository.deleteAll(); - } + repository.saveAndFlush(new User("foo", "bar", "foo@bar.de")); + assertThat(transactionManager.getTransactionRequests(), is(1)); + } + @Test + public void unannotatedFinder() throws Exception { - @Test - public void simpleManipulatingOperation() throws Exception { + repository.findByEmailAddress("foo@bar.de"); + assertThat(transactionManager.getTransactionRequests(), is(0)); + } - repository.saveAndFlush(new User("foo", "bar", "foo@bar.de")); - assertThat(transactionManager.getTransactionRequests(), is(1)); - } + @Test + public void invokeTransactionalFinder() throws Exception { + repository.findByAnnotatedQuery("foo@bar.de"); + assertThat(transactionManager.getTransactionRequests(), is(1)); + } - @Test - public void unannotatedFinder() throws Exception { + @Test + public void invokeRedeclaredMethod() throws Exception { - repository.findByEmailAddress("foo@bar.de"); - assertThat(transactionManager.getTransactionRequests(), is(0)); - } + repository.findOne(1); + assertFalse(transactionManager.getDefinition().isReadOnly()); + } + public static class DelegatingTransactionManager implements PlatformTransactionManager { - @Test - public void invokeTransactionalFinder() throws Exception { + private PlatformTransactionManager txManager; + private int transactionRequests; + private TransactionDefinition definition; - repository.findByAnnotatedQuery("foo@bar.de"); - assertThat(transactionManager.getTransactionRequests(), is(1)); - } + public DelegatingTransactionManager(PlatformTransactionManager txManager) { + this.txManager = txManager; + } - @Test - public void invokeRedeclaredMethod() throws Exception { + public void commit(TransactionStatus status) throws TransactionException { - repository.findOne(1); - assertFalse(transactionManager.getDefinition().isReadOnly()); - } + txManager.commit(status); + } - public static class DelegatingTransactionManager implements - PlatformTransactionManager { + public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException { - private PlatformTransactionManager txManager; - private int transactionRequests; - private TransactionDefinition definition; + this.transactionRequests++; + this.definition = definition; + return txManager.getTransaction(definition); + } - public DelegatingTransactionManager(PlatformTransactionManager txManager) { + public int getTransactionRequests() { - this.txManager = txManager; - } + return transactionRequests; + } + public TransactionDefinition getDefinition() { - public void commit(TransactionStatus status) - throws TransactionException { + return definition; + } - txManager.commit(status); - } + public void resetCount() { + this.transactionRequests = 0; + this.definition = null; + } - public TransactionStatus getTransaction(TransactionDefinition definition) - throws TransactionException { + public void rollback(TransactionStatus status) throws TransactionException { - this.transactionRequests++; - this.definition = definition; - - return txManager.getTransaction(definition); - } - - - public int getTransactionRequests() { - - return transactionRequests; - } - - - public TransactionDefinition getDefinition() { - - return definition; - } - - - public void resetCount() { - - this.transactionRequests = 0; - this.definition = null; - } - - - public void rollback(TransactionStatus status) - throws TransactionException { - - txManager.rollback(status); - } - } + txManager.rollback(status); + } + } } diff --git a/src/test/java/org/springframework/data/jpa/support/MergingPersistenceUnitManagerUnitTests.java b/src/test/java/org/springframework/data/jpa/support/MergingPersistenceUnitManagerUnitTests.java index c5f6d05ee..193670973 100644 --- a/src/test/java/org/springframework/data/jpa/support/MergingPersistenceUnitManagerUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/support/MergingPersistenceUnitManagerUnitTests.java @@ -29,7 +29,6 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo; - /** * Unit test for {@link MergingPersistenceUnitManager}. * @@ -38,22 +37,20 @@ import org.springframework.orm.jpa.persistenceunit.MutablePersistenceUnitInfo; @RunWith(MockitoJUnitRunner.class) public class MergingPersistenceUnitManagerUnitTests { - @Mock - PersistenceUnitInfo oldInfo; + @Mock + PersistenceUnitInfo oldInfo; - @Mock - MutablePersistenceUnitInfo newInfo; + @Mock + MutablePersistenceUnitInfo newInfo; + @Test + public void addsUrlFromOldPUItoNewOne() throws MalformedURLException { - @Test - public void addsUrlFromOldPUItoNewOne() throws MalformedURLException { + MergingPersistenceUnitManager manager = new MergingPersistenceUnitManager(); + URL jarFileUrl = new URL("file:foo/bar"); - MergingPersistenceUnitManager manager = - new MergingPersistenceUnitManager(); - URL jarFileUrl = new URL("file:foo/bar"); - - when(oldInfo.getJarFileUrls()).thenReturn(Arrays.asList(jarFileUrl)); - manager.postProcessPersistenceUnitInfo(newInfo, oldInfo); - verify(newInfo).addJarFileUrl(jarFileUrl); - } + when(oldInfo.getJarFileUrls()).thenReturn(Arrays.asList(jarFileUrl)); + manager.postProcessPersistenceUnitInfo(newInfo, oldInfo); + verify(newInfo).addJarFileUrl(jarFileUrl); + } }