2010-08-26 2 views
0

Я пытаюсь реализовать общий DAO, используя сеансы контекста Hibernates. Следующим был мой снимок: |Как создать общий класс DAO с использованием сеансов контекстного меню Hibernate

import java.io.Serializable; 

public interface GenericDao<T, ID extends Serializable> { 

/** Persist the newInstance object into database */ 
ID create(T newInstance); 

/** 
    * Retrieve an object that was previously persisted to the database using 
    * the indicated id as primary key 
    */ 
T read(ID primaryKey); 

/** Save changes made to a persistent object. */ 
void update(T transientObject); 

/** Remove an object from persistent storage in the database */ 
void delete(T persistentObject); 
} 


import java.io.Serializable; 

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.springframework.transaction.annotation.Transactional; 

@Transactional 
@SuppressWarnings("unchecked") 
public class GenericDaoImpl<T, ID extends Serializable> implements 
    GenericDao<T, ID> { 
private SessionFactory sessionFactory; 

public void setSessionFactory(final SessionFactory sessionFactory) { 
    this.sessionFactory = sessionFactory; 
} 

@Override 
public ID create(final T newInstance) { 
    ID id = null; 
    final Session session = sessionFactory.openSession(); 
    final Transaction tx = session.beginTransaction(); 
    try { 
    id = (ID) session.save(newInstance); 
    tx.commit(); 
    session.close(); 
    } catch (final Exception e) { 
    if (tx != null) { 
    tx.rollback(); 
    } 
    e.printStackTrace(); 
    } finally { 
    if (session.isOpen()) { 
    session.close(); 
    } 
    } 
    return id; 
} 

@Override 
public T read(final ID primaryKey) { 
    T id = null; 
    final Session session = sessionFactory.openSession(); 
    final Transaction tx = session.beginTransaction(); 
    try { 
    id = (T) session.get(T, primaryKey); 
    tx.commit(); 
    session.close(); 
    } catch (final Exception e) { 
    if (tx != null) { 
    tx.rollback(); 
    } 
    e.printStackTrace(); 
    } finally { 
    if (session.isOpen()) { 
    session.close(); 
    } 
    } 
    return id; 
} 

@Override 
public void update(final T transientObject) { 
    final Session session = sessionFactory.openSession(); 
    final Transaction tx = session.beginTransaction(); 
    try { 
    session.saveOrUpdate(transientObject); 
    tx.commit(); 
    session.close(); 
    } catch (final Exception e) { 
    if (tx != null) { 
    tx.rollback(); 
    } 
    e.printStackTrace(); 
    } finally { 
    if (session.isOpen()) { 
    session.close(); 
    } 
    } 
} 

@Override 
public void delete(final T persistentObject) { 
    final Session session = sessionFactory.openSession(); 
    final Transaction tx = session.beginTransaction(); 
    try { 
    session.delete(persistentObject); 
    tx.commit(); 
    session.close(); 
    } catch (final Exception e) { 
    if (tx != null) { 
    tx.rollback(); 
    } 
    e.printStackTrace(); 
    } finally { 
    if (session.isOpen()) { 
    session.close(); 
    } 
    } 
} 
} 

ApplicationContext:

<bean id="domainDao" class="com.foo.dao.DomainDao"> 
    <property name="sessionFactory"> 
    <ref bean="sessionFactory"></ref> 
    </property> 

</bean> 

<bean id="domainDao2" class="com.foo.dao.GenericDaoImpl"> 
    <property name="sessionFactory"> 
    <ref bean="sessionFactory"></ref> 
    </property> 

</bean> 
<tx:annotation-driven transaction-manager="txManager" /> 


<bean id="txManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

Ours это новое приложение, которое мы пытаемся реализовать с помощью Spring 3.0.3 и Hibernate 3.5.5.

Q1. Хотя я действительно выполнял его и работаю, сделал ли я правильно?

Q2. Как я могу реализовать операцию find() с использованием дженериков?

id = (T) session.get(T, primaryKey); 

Эта строка дает ошибку при компиляции.

ОБНОВЛЕНИЕ: Ошибка в том, что первый параметр имеет тип Class.

public Object get(Class clazz, Serializable id) 
      throws HibernateException 

Q3. Как конвертировать T в T.class?

+1

Пожалуйста, не говорите нам, что сборник ошибка в том, что гораздо интереснее догадываться. – skaffman

+0

Извините, я этого не понял. Вы серьезно или это саркастично: S – HanuAthena

+0

Это был сарказм. Что касается Q3, информация типа Generics удаляется во время компиляции и, следовательно, недоступна во время выполнения. Вам нужно передать фактический класс и запомнить его там, где вам это нужно. – hiergiltdiestfu

ответ

2

Дженерики не могут использоваться таким образом. Измените свой GenericDAOImpl, чтобы иметь конструктор, который берет класс и использует этот класс в вызове session.get. См. Пример ниже (он использует JPA вместо Hibernate конкретных классов).

public class GenericDao<T> { 

    @PersistenceContext 
    private EntityManager em; 

    public EntityManager em() { 
     return em; 
    } 

    public void create(final T entity) { 
     em.persist(entity); 
    } 

    public void update(final T entity) { 
     em.merge(entity); 
    } 

    protected T get(final Class<T> type, final String id) { 
     return em.find(type, id); 
    } 

    public void delete(final T entity) { 
     em.remove(entity); 
    } 

} 

public class PersonDao extends GenericDao<Person>{ 

    public Person get(final String id) { 
     return get(Person.class, id); 
    } 

} 

Кроме того, лучше ставить @Transactional аннотаций на бизнес или услуг передачи данных, а не на DAO,.

4

Следующая прием часто используется в общих классах DAO для доступа к параметрам типа фактических подклассов:

public abstract class GenericDAO<T, ID extends Serializable> { 
    private Class<T> persistentClass; 
    ... 

    @SuppressWarnings("unchecked") 
    public GenericDAO() { 
     this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
    } 

    public T get(ID id) { 
     return (T) session.get(persistentClass, id); 
    } 

    ... 
} 

и фактической DAO подкласса:

public class FooDAO extends GenericDAO<Foo, Long> {} 

 Смежные вопросы

  • Нет связанных вопросов^_^