28

トランザクション管理にSpringFrameworkトランザクションアノテーションを使用しており、以下のようにabstract classアノテーションが付け@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

誰かが私がこの矛盾を解決するのを手伝ってくれる?

4

2 に答える 2

42

はい、注釈が@Inherited追加されていれば可能です。たとえば、@Transactional注釈には。があり@Inheritedます。

ドキュメントから:

注釈タイプが自動的に継承されることを示します。継承されたメタアノテーションがアノテーションタイプ宣言に存在し、ユーザーがクラス宣言でアノテーションタイプをクエリし、クラス宣言にこのタイプのアノテーションがない場合、クラスのスーパークラスは自動的にアノテーションタイプを照会されます。このプロセスは、このタイプのアノテーションが見つかるか、クラス階層の最上位(オブジェクト)に到達するまで繰り返されます。このタイプのアノテーションを持つスーパークラスがない場合、クエリは問題のクラスにそのようなアノテーションがないことを示します。

このメタアノテーションタイプは、アノテーション付きタイプがクラス以外のものにアノテーションを付けるために使用される場合は効果がないことに注意してください。このメタアノテーションは、アノテーションがスーパークラスから継承されるだけであることにも注意してください。実装されたインターフェースの注釈は効果がありません。

のドキュメント@Transactional

@Target(value={METHOD,TYPE})
@Retention(value=RUNTIME)
@Inherited
@Documented
public @interface Transactional

オフトピック:Javaでは、注釈をサブタイプ化することはできません。

于 2012-05-15T08:28:15.187 に答える
19

アノテーションの継承は、基本的にメソッドまたはフィールドの継承と同じように機能します。

リフレクションを介してのみ注釈にアクセスできるため、次の2つの基本的な方法がありますClass

  • getAnnotations()現在のクラスとそのスーパークラスのすべてのアノテーションを返します
  • getDeclaredAnnotations()現在のクラスのすべてのアノテーションを返します

あなたがリンクした記事が話している問題は、メソッドが定義されているクラスへのMethod#getAnnotation(...)アクセスdeclaredAnnotations()です。これは、上記のように、そのクラスで定義されたアノテーションのみを返し、スーパークラスのアノテーションは返しません。

つまり、アノテーションが付けられたメソッドの1つをオーバーライドする場合は、@Transactionalそこにアノテーションを追加する必要があります(または、フレームワークがクラ​​スアノテーションも調べる場合は、で@Transactional宣言されているものを見つける必要がありますAbstractMaqraaService)。

于 2012-05-15T08:27:04.603 に答える