powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / А вы используете Hibernate Based Generic DAO?
47 сообщений из 47, показаны все 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
А вы используете Hibernate Based Generic DAO?
    #38319564
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerто что транзакции сами это круто, но у вас методы дао транзакционные, так что принципиальной разницы с первым вариантом нет, и главная проблема осталась

Дефолтный Propagation=REQUIRED, а это значит, что используется внешняя транзакция, если она есть. Поэтому эти методы могут работать как в одной общей транзкации так и в собственной единственной.


javapeckerИ если нужно только автоматическое управление транзакциями, достаточно использовать динамик прокси, и не таскать за собой спринг
?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319584
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczТаки без копипаста вообще никак? sessionFactory.getCurrentSession() стоило оформить в отдельный метод. Инкапсуляция наше всё.А на кой выводить в отдельный метод? Только чтобы букав было чуть-чуть меньше? Если в одном методе встречается два и более обращения, то использую уже переменную. А в чем профит этого приватного метода?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319587
javapecker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,
Дефолтный Propagation=REQUIRED, а это значит, что используется внешняя транзакция, если она есть
красота, я думал там просто все, раз @transactional, значит в транзакции
?
Если все что нужно получить, это управление транзакциями, можно сделать динамический прокси, который будет перехватывать методы бизнес уровня и оборачивать их в транзакции. При этом спринг или возможности EE не понадобятся.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319592
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javapeckerЕсли все что нужно получить, это управление транзакциями, можно сделать динамический прокси, который будет перехватывать методы бизнес уровня и оборачивать их в транзакции. При этом спринг или возможности EE не понадобятся.
Если вспомнить про такие вещи как Propagation, Isolation, JTA/XA то писать свой велосипед уже не захочется.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319769
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruckBlazkowiczТаки без копипаста вообще никак? sessionFactory.getCurrentSession() стоило оформить в отдельный метод. Инкапсуляция наше всё.А на кой выводить в отдельный метод? Только чтобы букав было чуть-чуть меньше? Если в одном методе встречается два и более обращения, то использую уже переменную. А в чем профит этого приватного метода?

В том что это инфраструктура, которая не решает бизнес-задачи и имеет тенденцию меняться\разраться\забываться\дополняться. Это просто инкапсуляция и этим все сказано.

В этом случае некритично, но очевидно что чем аккуратнее код, тем лучше.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38319790
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или я чего-то не понимаю, или прав ... Для "красоты" предлагается сделать приватную функцию типа
Код: java
1.
2.
3.
private Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
}

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

IDVsbruckТак? В этом случае при каждой необходимости получить сессию надо дергать фабрику?
И?

IDVsbruckЧем это лучше, чем получить приватную переменную типа Session в методе и пользоватья ею? Или я ошибаюсь?
Переменная в многопоточном окружении как себя вести будет?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38320405
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Н-да, за многопоточность я не подумал. Но это сразу толкает на мысль: если в методе более одной строки с зависимым кодом, то сразу ставить synchronized?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38320420
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruckболее одной строки с зависимым кодом
Что такое "зависимый код"??

IDVsbruck, то сразу ставить synchronized?
synchronized это убийца производительности сервера.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38320529
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczЧто такое "зависимый код"??
Ну, навскидку: в pojo есть поле (поля), помеченные как @Transient, для удобства использования в сервисах и представлениях, которые заполняются в DAO (Repository). Механизм заполнения простой: строка 1 - получение сущности, строка 2 - получение объекта или набора объектов, используя данные объекта из строки 1, строка 3 - заполнение Transient-поля объекта полученными объектами из строки 2. Получается, для высоконагруженного приложения чревато подобное использование?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38320547
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruck,

Няня, я у них поел. Но, судя по описанию, это и есть пример Anemic Model. Не понятно с какого перепугу DAO заполняет вычислимые поля сущностей. Если сущности сами могут вычислять значения, имея ссылки на остальные сущности.
Ну, и намешали всё в кучу. POJO тут вообще не при чем. Класс со свойствами называется Bean. Bean, который хранится в базе это Entity. POJO - вообще не о том.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321184
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да ладно, пусть не POJO, пусть просто объект-сущность. Так как поступать в описанной ситуации?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321197
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruckДа ладно, пусть не POJO, пусть просто объект-сущность. Так как поступать в описанной ситуации?
DAO вычитывает связаные объекты. DAO ничего не вычисляет. Вычислимые свойства сущности считают сами.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321244
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я не спорю. Просто ты затронул очень важный момент, на котором я не особо акцентировался. И привел схожий пример, когда надо заполнить Transient-поле бина-сущности данными, которые не обязательно должны быть заполнены (при вызове метода указываю флаг для указания - нужно ли заполнять поля - для снижения нагрузки, когда такие поля не нужны). Считать самим свои поля, как ты говоришь, - не совсем понятно, так как в методы бина не засунешь вычитку из базы - модель есть модель и засорять сервисными функциями неправильно. Делать раздельные сервисы - хрен с ними, можно и сделать, но проблему это не решит: запросом я получаю бин, следующей строкой кода вызываю метод другого сервиса - уже угроза использования разными потоками.
Отсюда и вопрос: как действительно правильно идеологически и функционально реализовать подобные "нюансы"?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321257
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruckЯ не спорю. Просто ты затронул очень важный момент, на котором я не особо акцентировался. И привел схожий пример, когда надо заполнить Transient-поле бина-сущности данными, которые не обязательно должны быть заполнены (при вызове метода указываю флаг для указания - нужно ли заполнять поля - для снижения нагрузки, когда такие поля не нужны). Считать самим свои поля, как ты говоришь, - не совсем понятно, так как в методы бина не засунешь вычитку из базы - модель есть модель и засорять сервисными функциями неправильно. Делать раздельные сервисы - хрен с ними, можно и сделать, но проблему это не решит: запросом я получаю бин, следующей строкой кода вызываю метод другого сервиса - уже угроза использования разными потоками.
Отсюда и вопрос: как действительно правильно идеологически и функционально реализовать подобные "нюансы"?
У вас похоже смешались кони, люди.. Вы точно не путаете transient и lazy? transient - это поле которое можно не сериализовать и вычислить на основе других полей, зачем вам лезть в базу?
Вы рассматриваете абсолютно anemic domain model. В варианте предложенном Blazkowicz, модель сама знает что она частино неинициализирована и обрабатывает это сама. как вариант в каждом геттере для transient поля вызывать init() и т.д.
А вот если вы имеете ввиду lazy, то тут да, есть определенные сложности.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321264
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruckЯ не спорю. Просто ты затронул очень важный момент, на котором я не особо акцентировался. И привел схожий пример, когда надо заполнить Transient-поле бина-сущности данными, которые не обязательно должны быть заполнены (при вызове метода указываю флаг для указания - нужно ли заполнять поля - для снижения нагрузки, когда такие поля не нужны). Считать самим свои поля, как ты говоришь, - не совсем понятно, так как в методы бина не засунешь вычитку из базы - модель есть модель и засорять сервисными функциями неправильно. Делать раздельные сервисы - хрен с ними, можно и сделать, но проблему это не решит: запросом я получаю бин, следующей строкой кода вызываю метод другого сервиса - уже угроза использования разными потоками.
Отсюда и вопрос: как действительно правильно идеологически и функционально реализовать подобные "нюансы"?
Покажи уже пример. Строить модель по твоим туманным подсказкам достаточно не просто.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321282
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
@Entity
@Access(AccessType.FIELD)
@Table(name = "entity")
public class Entity {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	Long id;

	String textField;

	@Transient
	List<OtherEntity> otherEntities;
	//getters, setters
}

@Repository
@Transactional
public class SomeRepositoryImpl implements SomeRepository {
	@Autowired private SessionFactory sessionFactory;

	public Entity getEntity(String criterion, boolean isFull) {
		if (critery == null) return null;
		Session session = sessionFactory.getCurrentSession();
		Entity entity = (Company) session.createQuery("FROM Entity entity WHERE entity.someField = :someCriterion").setString("someCriterion", criterion).uniqueResult();
		if (isFull) {
			List<OtherEntity> otherEntities = session.createQuery("FROM OtherEntity otherEntity WHERE ...").list();
			entity.setOtherEntities(otherEntities);
		}
		return entity;
	}
}


Вот, накидал на скорую руку. К примеру, нечто такое ...
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321477
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruck,

Смотри. Тут возможны, как минимум, три варианта.
1) Entity и AnotherEntity вообще никак не связаны. Что уже подозрительно, как так получилось, что в Java они связаны, а в базе нет?
Ты смело выкинул важный кусок из примера "FROM OtherEntity otherEntity WHERE ...", который показывает как именно связаны в базе. Hibernate умеет связывать даже по свойствам, если полноценных FK в базе нет. То есть этот случай как минимум подозрительный. Но если так, то выходит что мы просто засунули бизнес-логику в Repository, тогда как место ей в TransactionScript.
Код: java
1.
2.
3.
Entity e = repository.getEntity(key);
List<AnotherEntity> ael = repository.getOtherEntities(e);
CompoundEntity ce = CompoundEntity.create(e, ael);



2) Зачем нам @Transient свойство, если у нас коллекции и так по-умолчанию Lazy??
Чем этот код отличается от твоего, не очень понятно.
Код: java
1.
2.
3.
4.
Entity e = repository.getEntity(key);
if(isFull){
  useAnother(e.getAnotherEntity());
}



3) Твой код немного смахивает на управление Dynamic Association Fetching:
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html#querycriteria-dynamicfetching
То есть он имеет право на жизнь, когда нужно управлять Join/Sub-select/Lazy. Но для него есть готовый API, ты указываешь имя свойства и каким образом ты его хочешь грузить в текущем сценарии. API для этого уже есть. Реализовывать его самостоятельно особо не за чем.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321769
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну да, пример не очень удачный, действительно тут все можно заменить на Lazy.
Тогда подойду с другой стороны: скажем, удаление аккаунта пользователя ... в базе как минимум 8-10 таблиц так или иначе ссылаются на сущность, причем, некоторые имеют FK на уровне базы, другие нет (тут вижу замечание, что надо связать на уровне базы, но не хочу - слишком много завязано). Поэтому удаление делаю пошагово: запросами удаляю "слабо-зависимые" сущности, затем основную. В любом случае, это несколько строк. Как обезопаситься при многопоточном обращении?
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38321814
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruckНу да, пример не очень удачный, действительно тут все можно заменить на Lazy.
Тогда подойду с другой стороны: скажем, удаление аккаунта пользователя ... в базе как минимум 8-10 таблиц так или иначе ссылаются на сущность, причем, некоторые имеют FK на уровне базы, другие нет (тут вижу замечание, что надо связать на уровне базы, но не хочу - слишком много завязано). Поэтому удаление делаю пошагово: запросами удаляю "слабо-зависимые" сущности, затем основную. В любом случае, это несколько строк. Как обезопаситься при многопоточном обращении?

какую проблему вы видите в многопоточности? В вашей ситуации многопоточность разруливается на уровне транзакций базы данных.
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38322285
IDVsbruck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да уж, это многопоточность меня сильно накрыла. Основную ошибку я осознал: для небольшого проекта я между @Controller и @Repository не стал ставить @Service, возложив его функции на @Repository, отсюда такая сумятица. Так как я окончательно себя запутал, решил исходить из scope создаваемых Spring-компонентов (@Component): уже понятно, что @Repository - это по дефолту синглтон, отсюда нюансы работы в многопоточной среде; методы @Controller'а вызываются в сессионном контексте (или request). А что по поводу @Service? - Его видимость определяется контекстом контроллера или иным способом? Как бы из определения и сути данного компонента понятно, что потоки при вызове методов сталкиваться не должны, но все интересно мнение. Вопрос христоматийный, это понятно, но видимо, что я неправильно задаю критерии поиска проблемы, поэтому ответы из доки не получил.

И вдогонку второй вопрос: а можно все же объединить @Service и @Repository, или если так хочется, то только раздувать @Controller? - Уж больно у меня ненужная получается прослойка-сервис ...
...
Рейтинг: 0 / 0
А вы используете Hibernate Based Generic DAO?
    #38322473
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IDVsbruck,

Объединить, как раз можно Controller и Service. Во-многих случаях, если Service просто делегирует вызов в Repository, то и надобности в нем нет. @Transactional можно повесить и на Controller.
Это же мнение не так давно высказывал IT на форуме архитектуры: http://rsdn.ru/forum/design
...
Рейтинг: 0 / 0
47 сообщений из 47, показаны все 2 страниц
Форумы / Java [игнор отключен] [закрыт для гостей] / А вы используете Hibernate Based Generic DAO?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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