Я нашел несколько руководств по созданию Hibernate DAO с дженериками, но все они используют EntityManager
вместо SessionFactory
. Мой вопрос заключается в том, как создать DAO с помощью дженериков с использованием SessionFactory
. У меня есть ниже до сих пор:Как реализовать Hibernate DAO с generics
Интерфейс:
public interface GenericDao<T> {
public void save(T obj);
public void update(T obj);
public void delete(T obj);
public T findById(long id);
}
Класс:
@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {
@Autowired
private SessionFactory sessionFactory;
public void save(T obj) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(obj);
tx.commit();
} catch (HibernateException e) {
if(tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public void update(T obj) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(obj);
tx.commit();
} catch (HibernateException e) {
if(tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public void delete(T obj) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.delete(obj);
tx.commit();
} catch (HibernateException e) {
if(tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public T findById(long id) {
// ??
return null;
}
Я не уверен, как идти о findById
с использованием дженериков. Я считаю, что другие методы правильные, но исправьте меня, если я ошибаюсь.
БОЛЬШОЙ ВОПРОС: Использует EntityManager
более полезный, чем использование SessionFactory
? Я видел несколько сообщений по этому вопросу, но хотел бы еще несколько мнений.
В Java генерические средства реализуются путем стирания, а ваш формальный параметр 'T' становится' Object' во время выполнения. Другими словами, во время выполнения тип 'T' не существует. Любой общий метод, который возвращает новый чеканный экземпляр 'T', поэтому потребует маркер типа времени выполнения, который метод может использовать, чтобы отразить тип экземпляра, который он должен будет создать. Более практичная подпись для 'findById (...)' поэтому 'public T findById (класс класс, long id)'. –
scottb
@scottb, так что токен класса будет использоваться для определения того, какой тип объекта должен возвращать метод? Как бы я это сделал?С примерами 'EntityManager' я увидел' entityManager.find (type.class, id); ', но я не уверен, как это сделать с помощью' SessionFactory'. –
Если тип, который вам нужно вернуть, имеет конструктор без аргументов, тогда самый простой способ динамически отличить новый экземпляр произвольного типа 'T' должен был бы использовать метод' newInstance() 'класса', например. 'T myObj = class.newInstance();'. В противном случае вам может понадобиться использовать отражение через объект 'Class ' для вызова соответствующего конструктора с аргументами. В таком методе «класс» в классе Class класс' играет роль маркера типа * времени выполнения *. В Java это иногда необходимо именно потому, что общие типы не существуют во время выполнения. –
scottb