DATAJPA-345 - Allow @Lock and @QueryHints to be used as meta-annotations.
@Lock and @QueryHints can now be used as meta annotations to create custom annotations to e.g. reuse a dedicated set of query hints.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,7 +30,7 @@ import javax.persistence.LockModeType;
|
||||
* @author Aleksander Blomskøld
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Lock {
|
||||
@@ -41,4 +41,4 @@ public @interface Lock {
|
||||
* @return
|
||||
*/
|
||||
LockModeType value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2011 the original author or authors.
|
||||
* Copyright 2008-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.jpa.repository;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -30,8 +31,9 @@ import javax.persistence.QueryHint;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface QueryHints {
|
||||
|
||||
/**
|
||||
|
||||
@@ -126,7 +126,7 @@ public class JpaQueryMethod extends QueryMethod {
|
||||
*/
|
||||
LockModeType getLockModeType() {
|
||||
|
||||
Lock annotation = method.getAnnotation(Lock.class);
|
||||
Lock annotation = findAnnotation(method, Lock.class);
|
||||
return (LockModeType) AnnotationUtils.getValue(annotation);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011 the original author or authors.
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -84,7 +84,7 @@ public enum LockModeRepositoryPostProcessor implements RepositoryProxyPostProces
|
||||
return invocation.proceed();
|
||||
}
|
||||
|
||||
Lock annotation = method.getAnnotation(Lock.class);
|
||||
Lock annotation = AnnotationUtils.findAnnotation(method, Lock.class);
|
||||
LockModeType lockMode = (LockModeType) AnnotationUtils.getValue(annotation);
|
||||
TransactionSynchronizationManager.bindResource(method, lockMode == null ? NULL : lockMode);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
@@ -37,6 +39,7 @@ import org.springframework.data.jpa.domain.sample.User;
|
||||
import org.springframework.data.jpa.repository.Lock;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.jpa.repository.QueryHints;
|
||||
import org.springframework.data.jpa.repository.sample.UserRepository;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
|
||||
@@ -60,7 +63,8 @@ public class JpaQueryMethodUnitTests {
|
||||
RepositoryMetadata metadata;
|
||||
|
||||
Method repositoryMethod, invalidReturnType, pageableAndSort, pageableTwice, sortableTwice, modifyingMethod,
|
||||
nativeQuery, namedQuery, findWithLockMethod, invalidNamedParameter, findsProjections, findsProjection;
|
||||
nativeQuery, namedQuery, findWithLockMethod, invalidNamedParameter, findsProjections, findsProjection,
|
||||
withMetaAnnotation;
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
@@ -85,6 +89,8 @@ public class JpaQueryMethodUnitTests {
|
||||
|
||||
findsProjections = ValidRepository.class.getMethod("findsProjections");
|
||||
findsProjection = ValidRepository.class.getMethod("findsProjection");
|
||||
|
||||
withMetaAnnotation = ValidRepository.class.getMethod("withMetaAnnotation");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -221,7 +227,7 @@ public class JpaQueryMethodUnitTests {
|
||||
@Test
|
||||
public void considersAnnotatedNamedQueryName() {
|
||||
JpaQueryMethod queryMethod = new JpaQueryMethod(namedQuery, metadata, extractor);
|
||||
assertThat(queryMethod.getNamedQueryName(), is("Foo.bar"));
|
||||
assertThat(queryMethod.getNamedQueryName(), is("HateoasAwareSpringDataWebConfiguration.bar"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,7 +262,7 @@ public class JpaQueryMethodUnitTests {
|
||||
public void returnsDefaultCountQueryNameBasedOnConfiguredNamedQueryName() {
|
||||
|
||||
JpaQueryMethod method = new JpaQueryMethod(namedQuery, metadata, extractor);
|
||||
assertThat(method.getNamedCountQueryName(), is("Foo.bar.count"));
|
||||
assertThat(method.getNamedCountQueryName(), is("HateoasAwareSpringDataWebConfiguration.bar.count"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,6 +299,20 @@ public class JpaQueryMethodUnitTests {
|
||||
assertThat(new JpaQueryMethod(findsProjection, metadata, extractor).isQueryForEntity(), is(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-345
|
||||
*/
|
||||
@Test
|
||||
public void detectsLockAndQueryHintsOnIfUsedAsMetaAnnotation() {
|
||||
|
||||
JpaQueryMethod method = new JpaQueryMethod(withMetaAnnotation, metadata, extractor);
|
||||
|
||||
assertThat(method.getLockModeType(), is(LockModeType.OPTIMISTIC_FORCE_INCREMENT));
|
||||
assertThat(method.getHints(), hasSize(1));
|
||||
assertThat(method.getHints().get(0).name(), is("foo"));
|
||||
assertThat(method.getHints().get(0).value(), is("bar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface to define invalid repository methods for testing.
|
||||
*
|
||||
@@ -334,7 +354,7 @@ public class JpaQueryMethodUnitTests {
|
||||
@Query(value = "query", nativeQuery = true)
|
||||
List<User> findByLastname(String lastname);
|
||||
|
||||
@Query(name = "Foo.bar")
|
||||
@Query(name = "HateoasAwareSpringDataWebConfiguration.bar")
|
||||
List<User> findByNamedQuery();
|
||||
|
||||
@Lock(LockModeType.PESSIMISTIC_WRITE)
|
||||
@@ -344,5 +364,15 @@ public class JpaQueryMethodUnitTests {
|
||||
List<Integer> findsProjections();
|
||||
|
||||
Integer findsProjection();
|
||||
|
||||
@CustomAnnotation
|
||||
void withMetaAnnotation();
|
||||
}
|
||||
|
||||
@Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
|
||||
@QueryHints(@QueryHint(name = "foo", value = "bar"))
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface CustomAnnotation {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user