Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / А вы используете Hibernate Based Generic DAO? / 25 сообщений из 47, страница 1 из 2
03.07.2013, 10:55:25
    #38318265
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
Собственно, практикуете ли вы?
...
Рейтинг: 0 / 0
03.07.2013, 11:00:10
    #38318273
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
Generic DAO - да. Что значит Hibernate Based - не знаю.
...
Рейтинг: 0 / 0
03.07.2013, 14:47:09
    #38318835
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
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
03.07.2013, 14:56:12
    #38318853
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
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
03.07.2013, 14:58:17
    #38318861
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
Гоню. HibernateDaoSupport в Spring-е оно называется.
...
Рейтинг: 0 / 0
03.07.2013, 14:58:55
    #38318863
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
...
Рейтинг: 0 / 0
03.07.2013, 15:15:55
    #38318922
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
А ещё рекомендую посмотреть 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
03.07.2013, 15:18:49
    #38318933
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
Blazkowicz,

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

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

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

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

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

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

Так а что же вы порекомендуете как best practices?
...
Рейтинг: 0 / 0
03.07.2013, 15:45:46
    #38319009
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
...
Рейтинг: 0 / 0
03.07.2013, 15:51:18
    #38319021
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
Тут, кстати ещё одна интересная тема есть.
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
03.07.2013, 15:56:43
    #38319029
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
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
03.07.2013, 16:05:10
    #38319045
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
scymaks,

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

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

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

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

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

То есть получается Repositories - классы необходимые для персистенции данных (сохранение данных в БД, обновление данных в БД, удаление данных из БД, загрузка данных из БД), а Services это классы, которые выполняют бизнес логику, на которую и нужно навешать Transactional?
...
Рейтинг: 0 / 0
03.07.2013, 16:43:25
    #38319151
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
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
03.07.2013, 18:02:19
    #38319360
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
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
03.07.2013, 18:58:45
    #38319462
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
scymaks,
а в чем отличие от вашего первого варианта?
...
Рейтинг: 0 / 0
03.07.2013, 19:11:57
    #38319473
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
javapecker,

Ну как же?!

Транзакции сами открываются и завершаются.
...
Рейтинг: 0 / 0
03.07.2013, 19:25:44
    #38319488
javapecker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
scymaks,
то что транзакции сами это круто, но у вас методы дао транзакционные, так что принципиальной разницы с первым вариантом нет, и главная проблема осталась:
Blazkowicz Во-вторых если нам вдруг надо две операции внутри одной транзакции провернуть, что куда нам идти с такими нуждами?
И если нужно только автоматическое управление транзакциями, достаточно использовать динамик прокси, и не таскать за собой спринг
...
Рейтинг: 0 / 0
03.07.2013, 20:17:37
    #38319549
scymaks
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
А вы используете Hibernate Based Generic DAO?
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
Форумы / Java [игнор отключен] [закрыт для гостей] / А вы используете Hibernate Based Generic DAO? / 25 сообщений из 47, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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