5

基本的な CRUD 機能を取得するために継承できるリポジトリ クラスを作成しようとしています。EntityManager.find(..) には Class 引数が必要です。ただし、それに渡すことはできませんT(何らかの理由でまだ理解できません...タイプ消去)。そこで、エンティティ クラスを返すメソッドを見つけ、別の質問から追加しました。まず第一に、それはどのように機能し、第二に、パフォーマンスに大きな影響を与えるでしょうか? リフレクションを使用していることがわかります。

@Stateless
public abstract class AbstractSqlRepository<T> implements Repository<T> {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public void create(T entity) {
        entityManager.persist(entity);
    }

    @Override
    public T find(int id) {
        return entityManager.find(getEntityClass(), id);
    }

    @Override
    public T update(T entity) {
        return entityManager.merge(entity);
    }

    @Override
    public void remove(T entity) {
        entityManager.remove(entity);
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public Class<T> getEntityClass() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();

        return (Class<T>) genericSuperclass.getActualTypeArguments()[0];
    }
}

新しいアプローチ:

@Stateless
public abstract class AbstractSqlRepository<T> implements Repository<T> {

    @PersistenceContext
    private EntityManager entityManager;
    private Class<T> clazz;

    public AbstractSqlRepository(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public void create(T entity) {
        entityManager.persist(entity);
    }

    @Override
    public T find(int id) {
        return entityManager.find(clazz, id);
    }

    @Override
    public T update(T entity) {
        return entityManager.merge(entity);
    }

    @Override
    public void remove(T entity) {
        entityManager.remove(entity);
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }
}

public class QuestionSqlRepository extends AbstractSqlRepository implement QuestionRepository {

public QuestionSqlRepository() {
    super(Question.class);
}

}

これは悪いアプローチですか?

4

1 に答える 1

2

リフレクションはオーバーヘッドを追加すると述べられていますが、私の意見では、毎回オブジェクトのクラスを取得する必要はありません。

最初にそれを見つけて、後で null をチェックするだけです。これにより、スーパー クラス メソッドを呼び出す場合と比較して、オーバーヘッドがほとんど追加されません。

コンストラクター パラメーターに対する唯一の反論は、クラスが POJO にならないということです。

サンプルコードは次のとおりです。

@SuppressWarnings("unchecked")
public class HibernateBaseDao<T, Pk extends Serializable> implements Dao<Pk, T> {

    // ...
    private Class<T> type;

    // ...

    public Class<T> getType() {

        if (this.type == null) {

            ParameterizedType parameterizedType = (ParameterizedType) (this
                    .getClass().getGenericSuperclass());

            while (!(parameterizedType instanceof ParameterizedType)) {
                parameterizedType = (ParameterizedType) parameterizedType
                        .getClass().getGenericSuperclass();
            }

            this.type = (Class<T>) parameterizedType.getActualTypeArguments()[0];

        }

        return this.type;
    }

    @Override
    public T load(Pk id) {

        return (T) this.sessionFactory.getCurrentSession().load(this.getType(),
                id);
    }

    @Override
    public T get(Pk id) {
        return (T) this.sessionFactory.getCurrentSession().get(this.getType(),
                id);
    }

}
于 2012-10-25T19:08:05.907 に答える