2012-10-25 10 views
5

erben kann Ich versuche, eine Repository-Klasse zu erstellen, von der ich erben kann, um grundlegende CRUD-Funktionalität abzurufen. Die EntityManager.find (..) benötigt ein Class-Argument. Sie können jedoch nicht T zu ihm (aus irgendeinem Grund verstehe ich noch nicht ... Art löschen). Also habe ich die Methode gefunden, die die Entity-Klasse zurückgibt und sie aus einer anderen Frage, die ich gesehen habe, hinzugefügt hat. Vor allem, wie funktioniert es, und zweitens würde es viel Einfluss auf die Leistung haben? Ich sehe es als Reflexion.Erstellen eines generischen DAO für JPA, das ich von

@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]; 
    } 
} 

Neuer Ansatz:

@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; 
    } 
} 

und

public class QuestionSqlRepository erweitert AbstractSqlRepository implementiert QuestionRepository {

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

}

Ist das ein schlechter Ansatz?

+0

Reflexion wird Auswirkungen auf die Leistung haben. Du müsstest versuchen zu sehen, ob es dein Projekt zu sehr beeinflusst hat. Schöne Idee aber! – RNJ

+0

Nicht ganz so elegant könnte man immer ein Klasse classType-Objekt haben, das im Konstruktor gesetzt wird. Die Unterklasse constructur müsste nur super (this.getClass()) aufrufen. Es wäre schneller als die Reflexion, aber ein zusätzlicher Entwicklungsschritt. – JustinKSU

Antwort

2

Es wird gesagt, dass Reflexion wird Overhead hinzufügen, aber Sie müssen nicht die Klasse des Objekts jedes Mal meiner Meinung nach.

Finden Sie es das erste Mal und überprüfen Sie anschließend auf Null, dies fügt sehr wenig Overhead im Vergleich zu einer Super-Klasse-Methode aufrufen.

Das einzige Argument gegen den Konstruktorparameter ist, dass Ihre Klasse kein POJO sein wird. Hier

ist der Beispielcode:

@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); 
    } 

} 
Verwandte Themen