我使用Spring Framework事务注释进行事务管理,我有一个带注释的抽象类@Transactional
,如下所示:
package org.tts.maqraa.service;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Parts of this code have been copied from JARVANA site.
*
* @author Younis alomoush
*
*/
@Transactional(propagation=Propagation.REQUIRED)
public abstract class AbstractMaqraaService implements MaqraaService {
private Logger logger = LoggerFactory.getLogger(this.getClass());
private int defaultMaxResults = DEFAULT_MAX_RESULTS;
@PersistenceContext(type=PersistenceContextType.TRANSACTION)
private EntityManager em;
/**
* The {@link EntityManager} which is used by all query manipulation and
* execution in this DAO.
*
* @return the {@link EntityManager}
*/
public EntityManager getEntityManager(){
return em;
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#getTypes()
*/
public abstract Set<Class<?>> getTypes();
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#store(java.lang.Object)
*/
@Transactional(propagation = Propagation.REQUIRED)
public <T extends Object> T store(T toStore) {
return getEntityManager().merge(toStore);
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#remove(java.lang.Object)
*/
@Transactional(propagation = Propagation.REQUIRED)
public void remove(Object toRemove) {
toRemove = getEntityManager().merge(toRemove);
getEntityManager().remove(toRemove);
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#flush()
*/
@Transactional(propagation = Propagation.REQUIRED)
public void flush() {
getEntityManager().flush();
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#refresh(java.lang.Object)
*/
@Transactional(propagation = Propagation.SUPPORTS)
public void refresh(Object o) {
try {
if (o != null) {
if (o instanceof java.util.Collection) {
for (Iterator<?> i = ((Collection<?>) o).iterator(); i
.hasNext();) {
try {
refresh(i.next());
} catch (EntityNotFoundException x) {
// This entity has been deleted - remove it from the
// collection
i.remove();
}
}
} else {
if (getTypes().contains(o.getClass())) {
getEntityManager().refresh(o);
}
}
}
} catch (EntityNotFoundException x) {
// This entity has been deleted
}
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#setDefaultMaxResults(int)
*/
@Transactional(propagation = Propagation.SUPPORTS)
public void setDefaultMaxResults(int defaultMaxResults) {
this.defaultMaxResults = defaultMaxResults;
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#getDefaultMaxResults()
*/
public int getDefaultMaxResults() {
return defaultMaxResults;
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQueryByNameSingleResult(java
* .lang.String)
*/
@SuppressWarnings("unchecked")
public <T extends Object> T executeQueryByNameSingleResult(String queryName) {
return (T) executeQueryByNameSingleResult(queryName, (Object[]) null);
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQueryByNameSingleResult(java
* .lang.String, java.lang.Object[])
*/
@SuppressWarnings("unchecked")
public <T extends Object> T executeQueryByNameSingleResult(
String queryName, Object... parameters) {
Query query = createNamedQuery(queryName, DEFAULT_FIRST_RESULT_INDEX,
1, parameters);
return (T) query.getSingleResult();
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String)
*/
public <T extends Object> List<T> executeQueryByName(String queryName) {
return executeQueryByName(queryName, DEFAULT_FIRST_RESULT_INDEX,
getDefaultMaxResults());
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String,
* java.lang.Integer, java.lang.Integer)
*/
public <T extends Object> List<T> executeQueryByName(String queryName,
Integer firstResult, Integer maxResults) {
return executeQueryByName(queryName, firstResult, maxResults,
(Object[]) null);
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String,
* java.lang.Object[])
*/
public <T extends Object> List<T> executeQueryByName(String queryName,
Object... parameters) {
return executeQueryByName(queryName, DEFAULT_FIRST_RESULT_INDEX,
getDefaultMaxResults(), parameters);
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQueryByName(java.lang.String,
* java.lang.Integer, java.lang.Integer, java.lang.Object[])
*/
@SuppressWarnings("unchecked")
public <T extends Object> List<T> executeQueryByName(String queryName,
Integer firstResult, Integer maxResults, Object... parameters) {
Query query = createNamedQuery(queryName, firstResult, maxResults,
parameters);
return query.getResultList();
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#createNamedQuery(java.lang.String,
* java.lang.Integer, java.lang.Integer)
*/
public Query createNamedQuery(String queryName, Integer firstResult,
Integer maxResults) {
return createNamedQuery(queryName, firstResult, maxResults,
(Object[]) null);
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#createNamedQuery(java.lang.String,
* java.lang.Integer, java.lang.Integer, java.lang.Object[])
*/
public Query createNamedQuery(String queryName, Integer firstResult,
Integer maxResults, Object... parameters) {
Query query = getEntityManager().createNamedQuery(queryName);
if (parameters != null) {
for (int i = 0; i < parameters.length; i++) {
query.setParameter(i + 1, parameters[i]);
}
}
query.setFirstResult(firstResult == null || firstResult < 0 ? DEFAULT_FIRST_RESULT_INDEX
: firstResult);
if (maxResults != null && maxResults > 0)
query.setMaxResults(maxResults);
return query;
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#executeQuery(java.lang.String,
* java.lang.Integer, java.lang.Integer, java.lang.Object[])
*/
@SuppressWarnings("unchecked")
public <T extends Object> List<T> executeQuery(String queryString,
Integer firstResult, Integer maxResults, Object... parameters) {
Query query = createQuery(queryString, firstResult, maxResults,
parameters);
return query.getResultList();
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#executeQuery(java.lang.String,
* java.lang.Object[])
*/
@SuppressWarnings("unchecked")
public <T extends Object> List<T> executeQuery(String queryString,
Object... parameters) {
Query query = createQuery(queryString, DEFAULT_FIRST_RESULT_INDEX,
getDefaultMaxResults(), parameters);
return query.getResultList();
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQuerySingleResult(java.lang.
* String)
*/
@SuppressWarnings("unchecked")
public <T extends Object> T executeQuerySingleResult(String queryString) {
return (T) executeQuerySingleResult(queryString, (Object[]) null);
}
/*
* (non-Javadoc)
*
* @see
* org.skyway.spring.util.dao.JpaDao#executeQuerySingleResult(java.lang.
* String, java.lang.Object[])
*/
@SuppressWarnings("unchecked")
public <T extends Object> T executeQuerySingleResult(String queryString,
Object... parameters) {
Query query = createQuery(queryString, DEFAULT_FIRST_RESULT_INDEX, 1,
parameters);
return (T) query.getSingleResult();
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#createQuery(java.lang.String,
* java.lang.Integer, java.lang.Integer)
*/
public Query createQuery(String queryString, Integer firstResult,
Integer maxResults) {
return createQuery(queryString, firstResult, maxResults,
(Object[]) null);
}
/*
* (non-Javadoc)
*
* @see org.skyway.spring.util.dao.JpaDao#createQuery(java.lang.String,
* java.lang.Integer, java.lang.Integer, java.lang.Object[])
*/
public Query createQuery(String queryString, Integer firstResult,
Integer maxResults, Object... parameters) {
Query query = getEntityManager().createQuery(queryString);
if (parameters != null) {
for (int i = 0; i < parameters.length; i++) {
query.setParameter(i + 1, parameters[i]);
}
}
query.setFirstResult(firstResult == null || firstResult < 0 ? DEFAULT_FIRST_RESULT_INDEX
: firstResult);
if (maxResults != null && maxResults > 0)
query.setMaxResults(maxResults);
return query;
}
public final void log(LogLevel logLevel, String message,
Object... messageParam) {
switch (logLevel) {
case TRACE:
if (logger.isTraceEnabled()) {
logger.trace(message, messageParam);
}
break;
case DEBUG:
if (logger.isDebugEnabled()) {
logger.debug(message, messageParam);
}
break;
case INFO:
if (logger.isInfoEnabled()) {
logger.info(message, messageParam);
}
break;
case WARN:
if (logger.isWarnEnabled()) {
logger.warn(message, messageParam);
}
break;
case ERROR:
if (logger.isErrorEnabled()) {
logger.error(message, messageParam);
}
break;
default:
throw new IllegalArgumentException("Log Level is not defined: "
+ logLevel);
}
}
public final void log(LogLevel logLevel, String message, Throwable throwable) {
switch (logLevel) {
case TRACE:
if (logger.isTraceEnabled()) {
logger.trace(message, throwable);
}
break;
case DEBUG:
if (logger.isDebugEnabled()) {
logger.debug(message, throwable);
}
break;
case INFO:
if (logger.isInfoEnabled()) {
logger.info(message, throwable);
}
break;
case WARN:
if (logger.isWarnEnabled()) {
logger.warn(message, throwable);
}
break;
case ERROR:
if (logger.isErrorEnabled()) {
logger.error(message, throwable);
}
break;
default:
throw new IllegalArgumentException("Log Level is not defined: "
+ logLevel);
}
}
public enum LogLevel{
TRACE, DEBUG, INFO, WARN, ERROR;
}
}
另外,我有另一个具体的课程
package org.tts.maqraa.service;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.tts.maqraa.data.Student;
public class StudentsService extends AbstractMaqraaService {
@Override
public Set<Class<?>> getTypes() {
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(Student.class);
return set;
}
public Student registerStudent(Student student) {
Annotation [] annotation = StudentsService.class.getAnnotations();
System.out.println(annotation);
return this.store(student);
}
public Student editStudent(Student student){
return this.store(student);
}
public void deregisterStudent(Student student){
this.remove(student);
}
public List<Student> findAllStudents(){
return this.executeQueryByName("Student.findAll");
}
}
如果您注意到方法注册学生已经提供了用于检查我真正找到@Transactional注释的注释的代码。
这是一个矛盾,我有另一个关于继承注释的链接,它说根本没有继承。
点评此链接:http://fusionsoft-online.com/articles-java-annotations.php
任何人都可以帮我解决这个矛盾吗?
答案 0 :(得分:36)
是的,如果注释中添加了@Inherited
,则可以。例如,@Transactional
注释具有@Inherited
。
来自文档:
表示自动继承注释类型。如果 继承的元注释存在于注释类型上 声明,用户查询类的注释类型 声明,类声明没有注释 类型,然后将自动查询类的超类 注释类型。将重复此过程直到注释 找到此类型,或者类层次结构(Object)的顶部是 到达。如果没有超类具有此类型的注释,那么 查询将指示有问题的类没有这样的注释。
请注意,如果带注释,则此元注释类型无效 type用于注释除类之外的任何内容。另请注意 这个元注释只会导致注释继承自 超;已实现的接口上的注释无效。
@Transactional
的文档:
@Target(value={METHOD,TYPE}) @Retention(value=RUNTIME) @Inherited @Documented public @interface Transactional
关闭主题:您无法在Java中对注释进行子类型化。
答案 1 :(得分:16)
注释继承的工作方式与方法或字段的继承基本相同。
由于您只能通过反射访问注释,因此Class
中有两种基本方法:
getAnnotations()
返回当前类及其超类的所有注释getDeclaredAnnotations()
返回当前班级的所有注释您链接的文章所讨论的问题是Method#getAnnotation(...)
访问已定义方法的类的declaredAnnotations()
,如上所述,它只返回该类中定义的注释,而不是超级班。
这意味着如果覆盖用@Transactional
注释的方法之一,则必须在那里添加注释(或者如果框架也在类注释中查找,则应该找到声明的@Transactional
在AbstractMaqraaService
)。