Znalazłem kilka samouczków na temat tworzenia DAO Hibernate z generics, ale wszystkie one używają EntityManager
zamiast SessionFactory
. Moje pytanie brzmi: jak zbudować DAO z generycznymi używającymi SessionFactory
. Mam poniżej tej pory:W jaki sposób zaimplementować Hibernate DAO z generics
Interfejs:
public interface GenericDao<T> {
public void save(T obj);
public void update(T obj);
public void delete(T obj);
public T findById(long id);
}
Klasa:
@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;
}
jestem pewien, jak się do tego zabrać findById
używając rodzajowych. Wierzę, że inne metody są słuszne, ale popraw mnie, jeśli się mylę.
SIDE PYTANIE: Czy korzystanie EntityManager
bardziej korzystny niż przy użyciu SessionFactory
? Widziałem kilka postów na ten temat, ale chciałbym jeszcze kilku opinii.
W Javie, generics są realizowane przez wymazanie, a formalny parametr typu "T" staje się "Object" w czasie wykonywania. Innymi słowy, w czasie wykonywania wpisz 'T' nie istnieje. Każda ogólna metoda zwracająca nowo wygenerowaną instancję 'T' będzie zatem wymagać tokena typu działania, którego metoda może użyć do refleksyjnego określenia typu instancji, którą będzie musiał utworzyć. Bardziej praktycznym podpisem dla 'findById (...)' jest zatem 'public T findById (Class class, long id)'. –
scottb
@ scottb, aby użyć znacznika Class do określenia typu obiektu, który metoda musi zwrócić? Jak miałbym to dokładnie zrobić?W przykładach 'EntityManager' widziałem' entityManager.find (type.class, id); 'ale nie jestem pewien jak to zrobić z' SessionFactory'. –
Jeśli typ, który chcesz zwrócić, ma konstruktor bezargumentowy, wówczas najłatwiejszym sposobem dynamicznego wybrania nowej instancji dowolnego typu 'T' byłoby użycie metody' newInstance() 'z' klasy ', na przykład. 'T myObj = class.newInstance();'. W przeciwnym razie możesz potrzebować użyć odbicia za pomocą obiektu 'Class ', aby wywołać odpowiedni konstruktor z argumentami. W takiej metodzie "klasa" w klasie "Klasa " pełni rolę tokena * biegu czasu *. W Javie są one czasem konieczne właśnie dlatego, że typy ogólne nie istnieją w czasie wykonywania. –
scottb