* This class reads Spring's JDK 1.5+ {@link Transactional} annotation and exposes corresponding transaction
- * attributes to Spring's transaction infrastructure. Also supports EJB3's {@link javax.ejb.TransactionAttribute}
- * annotation (if present). This class may also serve as base class for a custom TransactionAttributeSource, or get
- * customized through {@link TransactionAnnotationParser} strategies.
- *
+ * attributes to Spring's transaction infrastructure. Also supports JTA 1.2's and EJB3's
+ * {@link javax.ejb.TransactionAttribute} annotation (if present). This class may also serve as base class for a
+ * custom TransactionAttributeSource, or get customized through {@link TransactionAnnotationParser} strategies.
+ *
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @since 1.2
@@ -124,43 +125,50 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
* @see org.springframework.transaction.interceptor.TransactionInterceptor#setTransactionAttributeSource
* @see org.springframework.transaction.interceptor.TransactionProxyFactoryBean#setTransactionAttributeSource
*/
- static class CustomAnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements
- Serializable {
+ @SuppressWarnings("serial")
+ static class CustomAnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
+ implements Serializable {
+
+ private static final boolean jta12Present = ClassUtils.isPresent("javax.transaction.Transactional",
+ CustomAnnotationTransactionAttributeSource.class.getClassLoader());
- private static final long serialVersionUID = 4841944452113159864L;
private static final boolean ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute",
CustomAnnotationTransactionAttributeSource.class.getClassLoader());
private final boolean publicMethodsOnly;
+
private final Set
* This implementation delegates to configured {@link TransactionAnnotationParser TransactionAnnotationParsers} for
- * parsing known annotations into Spring's metadata attribute class. Returns
* Can be overridden to support custom annotations that carry transaction metadata.
*
* @param ae the annotated method or class
- * @return TransactionAttribute the configured transaction attribute, or Transactional annotation or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.
+ * Create a default CustomAnnotationTransactionAttributeSource, supporting public methods that carry the
+ * {@code Transactional} annotation or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.
*/
public CustomAnnotationTransactionAttributeSource() {
this(true);
}
/**
- * Create a custom AnnotationTransactionAttributeSource, supporting public methods that carry the
- * Transactional annotation or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.
+ * Create a custom CustomAnnotationTransactionAttributeSource, supporting public methods that carry the
+ * {@code Transactional} annotation or the EJB3 {@link javax.ejb.TransactionAttribute} annotation.
*
- * @param publicMethodsOnly whether to support public methods that carry the Transactional annotation
- * only (typically for use with proxy-based AOP), or protected/private methods as well (typically used with
+ * @param publicMethodsOnly whether to support public methods that carry the {@code Transactional} annotation only
+ * (typically for use with proxy-based AOP), or protected/private methods as well (typically used with
* AspectJ class weaving)
*/
public CustomAnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSetnull if it's not
- * transactional.
+ * parsing known annotations into Spring's metadata attribute class. Returns {@code null} if it's not transactional.
* null if none was found
+ * @return TransactionAttribute the configured transaction attribute, or {@code null} if none was found
*/
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
@@ -220,6 +241,24 @@ class TransactionalRepositoryProxyPostProcessor implements RepositoryProxyPostPr
protected boolean allowPublicMethodsOnly() {
return this.publicMethodsOnly;
}
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof CustomAnnotationTransactionAttributeSource)) {
+ return false;
+ }
+ CustomAnnotationTransactionAttributeSource otherTas = (CustomAnnotationTransactionAttributeSource) other;
+ return (this.annotationParsers.equals(otherTas.annotationParsers)
+ && this.publicMethodsOnly == otherTas.publicMethodsOnly);
+ }
+
+ @Override
+ public int hashCode() {
+ return this.annotationParsers.hashCode();
+ }
}
/**
diff --git a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java
index 3f89ad5ac..194a1912f 100644
--- a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java
+++ b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryProxyPostProcessorUnitTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2014 the original author or authors.
+ * Copyright 2008-2015 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. You may obtain a copy of
@@ -15,6 +15,7 @@
*/
package org.springframework.data.repository.core.support;
+import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
@@ -24,11 +25,11 @@ import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
-import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.ListableBeanFactory;
@@ -38,6 +39,7 @@ import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.support.TransactionalRepositoryProxyPostProcessor.CustomAnnotationTransactionAttributeSource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAttribute;
+import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;
/**
@@ -57,8 +59,8 @@ public class TransactionRepositoryProxyPostProcessorUnitTests {
Map