powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / А вы используете Hibernate Based Generic DAO?
25 сообщений из 47, страница 1 из 2
А вы используете Hibernate Based Generic DAO?
    #38318265
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно, практикуете ли вы?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318273
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Generic DAO - да. Что значит Hibernate Based - не знаю.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318835
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

Я вот написал абстрактный DAO:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public interface AbstractDAO<Id, Entity> {
    Entity getById(Id id);

    List<Entity> getAll();

    void save(Entity entity);

    void update(Entity entity);

    void delete(Entity entity);

    void deleteById(Id id);
}



Теперь типа делаем реализацию основанную на Hibernate:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
abstract class HibernateBasedDAO<Id, Entity> implements AbstractDAO<Id, Entity> {
    @Autowired
    SessionFactory sessionFactory;

    @Override public void delete(Entity entity) {
        Session session = sessionFactory.openSession();

        Transaction transaction = session.beginTransaction();

        session.delete(entity);

        transaction.commit();

        session.close();
    }

    @Override public void save(Entity entity) {
        Session session = sessionFactory.openSession();

        Transaction transaction = session.beginTransaction();

        session.save(entity);

        transaction.commit();

        session.close();
    }

    @Override public void update(Entity entity) {
        Session session = sessionFactory.openSession();

        Transaction transaction = session.beginTransaction();

        session.update(entity);

        transaction.commit();

        session.close();
    }

    @Override public void deleteById(Id id) {
        Session session = sessionFactory.openSession();

        Transaction transaction = session.beginTransaction();

        /* session.delete(session.get(Entity.class, id)) - не работает, но как исправить не знаю пока. */

        transaction.commit();

        session.close();

    }

    @Override
    public Entity getById(Id id) {
        throw new UnsupportedOperationException();
    }

    @Override
    public List<Entity> getAll() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318853
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaks,
За такое старшие товарищи и втык могут сделать.
Код: java
1.
2.
3.
4.
5.
       Session session = sessionFactory.openSession();
       Transaction transaction = session.beginTransaction();
       ...
       transaction.commit();
       session.close();


Во-первых копипаст наше всё. Да?
Во-вторых если нам вдруг надо две операции внутри одной транзакции провернуть, что куда нам идти с такими нуждами?
И сессия пересоздаётся и закрывается на каждый пук?
В-третих .close() и не в finally блоке. Что с в случае Exception будет?
И в-четвертых уже даже спринговый AbstractHibernateDAO считается deprecated. А вы его криво изобретаете заново.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318861
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гоню. HibernateDaoSupport в Spring-е оно называется.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318863
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318922
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А ещё рекомендую посмотреть Spring Data для JPA.
http://static.springsource.org/spring-data/data-jpa/docs/current/reference/html/jpa.repositories.html#jpa.sample-app.finders.strategies
Возможность писать заросы методами, просто выносит мозг.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318933
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

Да на скорую руку же) Конечно же это не продакшн код)
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318943
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaksДа на скорую руку же) Конечно же это не продакшн код)
Отмазка не канает.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38318978
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На самом деле продакшн код был еще хуже.

У вас какой подход используется ?

Spring DATA +JPA?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319002
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaksНа самом деле продакшн код был еще хуже.
Ну, в самом херовом продакшн коде я кого хочешь за пояс заткну. У меня тут есть один проектик 3й год на саппорте...

scymaksУ вас какой подход используется?

У меня все проекты довольно старые, использовали, в основном, код аналогичный этому: 14516904 и HiberateDaoSupport.

scymaksSpring DATA +JPA?
А это я видел в одном новом проекте. Вызывает смешаные чувства.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319007
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

Так а что же вы порекомендуете как best practices?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319009
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319021
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут, кстати ещё одна интересная тема есть.
http://stackoverflow.com/questions/8550124/what-is-the-difference-between-dao-and-repository-patterns
То что сейчас называют DAO, уже достаточно давно не DAO, а Repository.
Задача DAO - инкапсулировать работу с базой данных. В основном, CRUD.
http://www.martinfowler.com/eaaCatalog/dataMapper.html

Но CRUD уже инкапсулирован в ORM. Поэтому Hibernate DAO это уже фактически Repository
http://martinfowler.com/eaaCatalog/repository.html
Этот паттер инкапсулирует запросы.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319029
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public interface AbstractDAO<Id, Entity> {
    Entity getById(Id id);

    List<Entity> getAll();

    void save(Entity entity);

    void update(Entity entity);

    void delete(Entity entity);

    void deleteById(Id id);
}



Код: java
1.
2.
interface UserDAO extends AbstractDAO<Integer, User> {
}



Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
@Repository
class HibernateBasedUserDAOImpl implements UserDAO {
    @Autowired
    private SessionFactory sessionFactory;

    @Override public void delete(User user) {
        sessionFactory.getCurrentSession().delete(user);
    }

    @Override public User getById(Integer id) {
        return (User) sessionFactory.getCurrentSession().get(User.class, id);
    }

    @Override public List<User> getAll() {
        return (List<User>) sessionFactory.getCurrentSession().createCriteria(User.class).list();
    }

    @Override public void save(User user) {
        sessionFactory.getCurrentSession().save(user);
    }

    @Override public void update(User user) {
        sessionFactory.getCurrentSession().update(user);
    }

    @Override public void deleteById(Integer id) {
        sessionFactory.getCurrentSession().delete(getById(id));
    }
}



+ добавить Transactional Manager и всё? Это есть Best Practices? Или я неверно понял?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319045
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaks,

Таки без копипаста вообще никак? sessionFactory.getCurrentSession() стоило оформить в отдельный метод. Инкапсуляция наше всё.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319069
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

да, надо бы выделить метод.

Ну а так , да? Добавить декларативное описание транзакций и всё?

А если нужны какие-нибудь хитрые запросы, тогда нужно создавать Query и просто исполнять его, без закрывания сессии?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319093
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaks Добавить декларативное описание транзакций и всё?
Да. Только надо понимать что Repository не управляет транзакциями. Транзакции привязаны к бизнес-логики.
Репозиторий просто глобально можно пометить транзакционным на всякий случай.

scymaks А если нужны какие-нибудь хитрые запросы, тогда нужно создавать Query и просто исполнять его, без закрывания сессии?
"Хитрость запросов" никак не связана с тем когда нужно закрывать сессию. Задача сессии отслеживать все изменения, а не "хитрые запросы".
http://martinfowler.com/eaaCatalog/unitOfWork.html
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319120
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,

То есть получается Repositories - классы необходимые для персистенции данных (сохранение данных в БД, обновление данных в БД, удаление данных из БД, загрузка данных из БД), а Services это классы, которые выполняют бизнес логику, на которую и нужно навешать Transactional?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319151
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaksBlazkowicz,
То есть получается Repositories - классы необходимые для персистенции данных (сохранение данных в БД, обновление данных в БД, удаление данных из БД, загрузка данных из БД), а Services это классы, которые выполняют бизнес логику, на которую и нужно навешать Transactional?

По Фаулеру немного не так.
"сохранение данных в БД, обновление данных в БД, удаление данных из БД, загрузка данных из БД" - это CRUD. Реализуется как DOA(DataMapper) или, в нашем случае - ORM.
Repository - это сложные запросы. CRUD просто для удобства делается через него же. Но Repository не реализует CRUD.
Service у Фаулера так и называется - Transaction Script. Так как его назначение это реализация бизнес-транзакций. Основной побочный эффект Transaction Script в том что разработчики забывают что какую-то логику можно и нужно инкапсулировать в Domain Model Entity. И в результате получается Anemic Domain Model, когда Transaction Script реализует сложные манипуляции со свойствами сущности, вместо того чтобы просто вызвать метод этой сущности.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319360
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz, большое спасибо за помощь!
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
@Repository
public class UserDAOImpl extends HibernateBasedDAO implements UserDAO {
    @Transactional
    @Override public User getById(Integer id) {
        return (User) getCurrentSession().get(User.class, id);
    }

    @Transactional
    @Override public List<User> getAll() {
        return (List<User>) getCurrentSession().createCriteria(User.class).list();
    }

    @Transactional
    @Override public void save(User user) {
        getCurrentSession().save(user);
    }

    @Transactional
    @Override public void update(User user) {
        getCurrentSession().update(user);
    }

    @Transactional
    @Override public void delete(User user) {
        getCurrentSession().delete(user);
    }

    @Transactional
    @Override public void deleteById(Integer id) {
        delete(getById(id));
    }
}



Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
    <bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

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

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>



Вот так получилось? Так уже лучше?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319462
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaks,
а в чем отличие от вашего первого варианта?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319473
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,

Ну как же?!

Транзакции сами открываются и завершаются.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319488
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
scymaks,
то что транзакции сами это круто, но у вас методы дао транзакционные, так что принципиальной разницы с первым вариантом нет, и главная проблема осталась:
Blazkowicz Во-вторых если нам вдруг надо две операции внутри одной транзакции провернуть, что куда нам идти с такими нуждами?
И если нужно только автоматическое управление транзакциями, достаточно использовать динамик прокси, и не таскать за собой спринг
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319549
scymaks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapecker,

эм..
нет проблемы.

вот такой код нормально отработал:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
@Transactional
public void f() {
    User u1 = new User();
    /* ... */

    save(u1);

    save(u2);

    throw new RuntimeException();
}



или вы не об этом?
...
Рейтинг: 0 / 0
25 сообщений из 47, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / А вы используете Hibernate Based Generic DAO?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]