DATAJPA-574 - Implementation of QueryDslPredicateExecutor now considers lock mode and query hints.
The Querydsl query creation now also leverages the CrudMethodMetadata instance held in SimpleJpaRepository to apply lock mode settings and query hints to the query to be executed.
This commit is contained in:
@@ -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<T, ID extends Serializable> 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<String, Object> hint : metadata.getQueryHints().entrySet()) {
|
||||
query.setHint(hint.getKey(), hint.getValue());
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<JPAQuery> createQuery() {
|
||||
|
||||
switch (provider) {
|
||||
case ECLIPSELINK:
|
||||
@@ -92,7 +93,7 @@ public class Querydsl {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public JPQLQuery createQuery(EntityPath<?>... paths) {
|
||||
public AbstractJPAQuery<JPAQuery> createQuery(EntityPath<?>... paths) {
|
||||
return createQuery().from(paths);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,6 +106,10 @@ public class SimpleJpaRepository<T, ID extends Serializable> implements JpaRepos
|
||||
this.crudMethodMetadata = crudMethodMetadata;
|
||||
}
|
||||
|
||||
protected CrudMethodMetadata getRepositoryMethodMetadata() {
|
||||
return crudMethodMetadata;
|
||||
}
|
||||
|
||||
protected Class<T> getDomainClass() {
|
||||
return entityInformation.getJavaType();
|
||||
}
|
||||
|
||||
@@ -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<Role> criteriaQuery;
|
||||
@Mock JpaEntityInformation<Role, Integer> information;
|
||||
@Mock TypedQuery<Role> query;
|
||||
@Mock TypedQuery<Role> 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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Role, Integer> {
|
||||
public interface RoleRepository extends CrudRepository<Role, Integer>, QueryDslPredicateExecutor<Role> {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -47,6 +50,15 @@ public interface RoleRepository extends CrudRepository<Role, Integer> {
|
||||
@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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user