Skip to content

Commit

Permalink
DATAJPA-574 - Implementation of QueryDslPredicateExecutor now conside…
Browse files Browse the repository at this point in the history
…rs 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.
  • Loading branch information
odrotbohm committed Jul 16, 2014
1 parent 2b4dfa2 commit 3467d92
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
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;
Expand All @@ -30,6 +32,7 @@
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;
Expand Down Expand Up @@ -136,6 +139,21 @@ public long count(Predicate predicate) {
* @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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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;
Expand Down Expand Up @@ -72,7 +73,7 @@ public Querydsl(EntityManager em, PathBuilder<?> builder) {
*
* @return
*/
public JPQLQuery createQuery() {
public AbstractJPAQuery<JPAQuery> createQuery() {

switch (provider) {
case ECLIPSELINK:
Expand All @@ -92,7 +93,7 @@ public JPQLQuery createQuery() {
*
* @return
*/
public JPQLQuery createQuery(EntityPath<?>... paths) {
public AbstractJPAQuery<JPAQuery> createQuery(EntityPath<?>... paths) {
return createQuery().from(paths);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public void setRepositoryMethodMetadata(CrudMethodMetadata crudMethodMetadata) {
this.crudMethodMetadata = crudMethodMetadata;
}

protected CrudMethodMetadata getRepositoryMethodMetadata() {
return crudMethodMetadata;
}

protected Class<T> getDomainClass() {
return entityInformation.getJavaType();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@
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;
Expand All @@ -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;

Expand Down Expand Up @@ -78,13 +81,13 @@ public void usesLockInformationAnnotatedAtRedeclaredMethod() {

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");
}

/**
Expand All @@ -100,4 +103,19 @@ public void usesMetadataAnnotatedAtRedeclaredFindOne() {

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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@
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)
Expand All @@ -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
*/
Expand Down

0 comments on commit 3467d92

Please sign in to comment.