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 d7695d854..5eccacd2a 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 @@ -18,8 +18,10 @@ package org.springframework.data.jpa.repository.support; import java.io.Serializable; import java.util.Collections; import java.util.List; +import java.util.Map.Entry; import javax.persistence.EntityManager; +import javax.persistence.LockModeType; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -30,6 +32,7 @@ import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.querydsl.SimpleEntityPathResolver; import com.mysema.query.jpa.JPQLQuery; +import com.mysema.query.jpa.impl.JPAQuery; import com.mysema.query.types.EntityPath; import com.mysema.query.types.OrderSpecifier; import com.mysema.query.types.Predicate; @@ -136,6 +139,21 @@ public class QueryDslJpaRepository extends SimpleJpa * @return the Querydsl {@link JPQLQuery}. */ protected JPQLQuery createQuery(Predicate... predicate) { - return querydsl.createQuery(path).where(predicate); + + JPAQuery query = querydsl.createQuery(path).where(predicate); + CrudMethodMetadata metadata = getRepositoryMethodMetadata(); + + if (metadata == null) { + return query; + } + + LockModeType type = metadata.getLockModeType(); + query = type == null ? query : query.setLockMode(type); + + for (Entry hint : metadata.getQueryHints().entrySet()) { + query.setHint(hint.getKey(), hint.getValue()); + } + + return query; } } diff --git a/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java b/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java index 44883ae03..dd920481c 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/Querydsl.java @@ -30,6 +30,7 @@ import com.mysema.query.jpa.EclipseLinkTemplates; import com.mysema.query.jpa.HQLTemplates; import com.mysema.query.jpa.JPQLQuery; import com.mysema.query.jpa.OpenJPATemplates; +import com.mysema.query.jpa.impl.AbstractJPAQuery; import com.mysema.query.jpa.impl.JPAQuery; import com.mysema.query.support.Expressions; import com.mysema.query.types.EntityPath; @@ -72,7 +73,7 @@ public class Querydsl { * * @return */ - public JPQLQuery createQuery() { + public AbstractJPAQuery createQuery() { switch (provider) { case ECLIPSELINK: @@ -92,7 +93,7 @@ public class Querydsl { * * @return */ - public JPQLQuery createQuery(EntityPath... paths) { + public AbstractJPAQuery createQuery(EntityPath... paths) { return createQuery().from(paths); } 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 67c9b2a98..c57e3ece8 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 @@ -106,6 +106,10 @@ public class SimpleJpaRepository implements JpaRepos this.crudMethodMetadata = crudMethodMetadata; } + protected CrudMethodMetadata getRepositoryMethodMetadata() { + return crudMethodMetadata; + } + protected Class getDomainClass() { return entityInformation.getJavaType(); } diff --git a/src/test/java/org/springframework/data/jpa/repository/CrudMethodMetadataIntegrationTests.java b/src/test/java/org/springframework/data/jpa/repository/CrudMethodMetadataIntegrationTests.java index de7835478..0bb0f3f03 100644 --- a/src/test/java/org/springframework/data/jpa/repository/CrudMethodMetadataIntegrationTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/CrudMethodMetadataIntegrationTests.java @@ -28,11 +28,13 @@ import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; +import org.hibernate.ejb.HibernateEntityManager; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.data.jpa.domain.sample.QRole; import org.springframework.data.jpa.domain.sample.Role; import org.springframework.data.jpa.repository.sample.RoleRepository; import org.springframework.data.jpa.repository.support.JpaEntityInformation; @@ -50,7 +52,8 @@ public class CrudMethodMetadataIntegrationTests { @Mock CriteriaBuilder builder; @Mock CriteriaQuery criteriaQuery; @Mock JpaEntityInformation information; - @Mock TypedQuery query; + @Mock TypedQuery typedQuery; + @Mock javax.persistence.Query query; RoleRepository repository; @@ -78,13 +81,13 @@ public class CrudMethodMetadataIntegrationTests { when(em.getCriteriaBuilder()).thenReturn(builder); when(builder.createQuery(Role.class)).thenReturn(criteriaQuery); - when(em.createQuery(criteriaQuery)).thenReturn(query); - when(query.setLockMode(any(LockModeType.class))).thenReturn(query); + when(em.createQuery(criteriaQuery)).thenReturn(typedQuery); + when(typedQuery.setLockMode(any(LockModeType.class))).thenReturn(typedQuery); repository.findAll(); - verify(query).setLockMode(LockModeType.READ); - verify(query).setHint("foo", "bar"); + verify(typedQuery).setLockMode(LockModeType.READ); + verify(typedQuery).setHint("foo", "bar"); } /** @@ -100,4 +103,19 @@ public class CrudMethodMetadataIntegrationTests { verify(em).find(Role.class, 1, expectedLockModeType, expectedLinks); } + + /** + * @see DATAJPA-574 + */ + @Test + public void appliesLockModeAndQueryHintsToQuerydslQuery() { + + when(em.getDelegate()).thenReturn(mock(HibernateEntityManager.class)); + when(em.createQuery(anyString())).thenReturn(query); + + repository.findOne(QRole.role.name.eq("role")); + + verify(query).setLockMode(LockModeType.READ); + verify(query).setHint("foo", "bar"); + } } 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 f34b54f86..976810bc6 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 @@ -21,15 +21,18 @@ import javax.persistence.QueryHint; import org.springframework.data.jpa.domain.sample.Role; import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.QueryHints; +import org.springframework.data.querydsl.QueryDslPredicateExecutor; import org.springframework.data.repository.CrudRepository; +import com.mysema.query.types.Predicate; + /** * Typing interface for {@code Role}. * * @author Oliver Gierke * @author Thomas Darimont */ -public interface RoleRepository extends CrudRepository { +public interface RoleRepository extends CrudRepository, QueryDslPredicateExecutor { /* * (non-Javadoc) @@ -47,6 +50,15 @@ public interface RoleRepository extends CrudRepository { @QueryHints(@QueryHint(name = "foo", value = "bar")) Role findOne(Integer id); + /* + * (non-Javadoc) + * @see org.springframework.data.querydsl.QueryDslPredicateExecutor#findOne(com.mysema.query.types.Predicate) + */ + @Override + @Lock(LockModeType.READ) + @QueryHints(@QueryHint(name = "foo", value = "bar")) + Role findOne(Predicate predicate); + /** * @see DATAJPA-509 */