powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring+Hibernate вопрос о работе с сессиями в DAO объектах
23 сообщений из 23, страница 1 из 1
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163455
snawa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Это какая-то базовая проблема настройки хибернейта, я в этом не силен. Друзья, поделитесь пожалуйста опытом, даже если это нубский вопрос

Конфигурация Spring:

Код: xml
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.
<bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"
        p:driverClass="${jdbc.driverClassName}"
        p:jdbcUrl="${jdbc.databaseurl}"
        p:user="${jdbc.username}"
        p:password="${jdbc.password}" />

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
    	<list>
           <value>com.checkout.core.model</value>
       </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">${jdbc.dialect}</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>            
            <prop key="hibernate.c3p0.min_size">10</prop>
			<prop key="hibernate.c3p0.max_size">200</prop>
			<prop key="hibernate.c3p0.timeout">90</prop>
			<prop key="hibernate.c3p0.max_statements">50</prop>
			<prop key="hibernate.c3p0.idle_test_period">3000</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>	

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
	<property name="sessionFactory" ref="sessionFactory" />
	<property name="maxResults" value="5000" />
</bean>

<bean id="abstractDAO" abstract="true" p:hibernateTemplate-ref="hibernateTemplate" class="com.checkout.core.dao.impl.AbstractDAOImpl" />



Реализация AbstractDAOImpl
Код: 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.
@Repository
public abstract class AbstractDAOImpl<T extends DataObject> extends HibernateDaoSupport implements AbstractDAO<T> {

	protected Criteria createCriteria() {
		return getSession().createCriteria(getObjectClass());
	}

	protected Criteria createCriteria(String alias) {
		return getSession().createCriteria(getObjectClass(), alias);
	}	

	public List<T> list(int fromIndex, int toIndex, String orderBy, boolean isAscending, Filter filter, Map<String, Object> context) {
		Criteria criteria = createCriteria();
		List<T> result = criteria.list();
		// DetachedCriteria criteria = DetachedCriteria.forClass(getObjectClass());
		// List<T> result = getHibernateTemplate().findByCriteria(criteria, fromIndex, toIndex - fromIndex);
		// criteria.setProjection(Projections.rowCount());
		// context.put(PersistenceService.TOTAL_COUNT, getHibernateTemplate().findByCriteria(criteria, 0, 1).iterator().next());
		return result;
	}

	public T get(Long id) {
		return (T) getSession().get(getObjectClass(), id);
		// return getHibernateTemplate().get(getObjectClass(), id);
	}
	.....................................
}



Проблема вот в чем - в реализации AbstractDAOImpl. Там должен по-хорошему должен использоваться hibernateTemplate, который оперирует DetachedCriteria. Если объект, например User выбрать например с помощью

Код: java
1.
2.
3.
DetachedCriteria criteria = DetachedCriteria.forClass(getObjectClass());
criteria.addRestriction(Restrictions.eq("id", 1));
User user = getHibernateTemplate().findByCriteria(criteria).iterator().next();



то потом у User'а проблемы с ленивой инициализацией коллекции getRoles() - если просто взять user.getRoles(), то получим Lazy initialization exception, также эксепшн выдает и Hibernate.initialize(user.getRoles());

Поэтому я сделал так, как сейчас в коде

Код: java
1.
2.
3.
Criteria criteria = getSession().createCriteria(getObjectClass());
criteria.addRestriction(Restrictions.eq("id", 1));
User user = criteria.list().iterator().next();


при этом сессия сохраняется и если взять user.getRoles(), то все пройдет без проблем - коллекция проинициализируется сама. Проблема в том, что эти коннекшны совсем не убиваются, а подвисают и после нескольких обновлений страницы браузера все виснет на выполнении criteria.list() - наверное коннекшны закончились. Для обработки коннекшнов я подключил к хибернейту c3p0 кэш

Да и вообще проблема не в способе создании Criteria, а в способе взятия сессий - в методе public T get(Long id) такая же проблема будет

Спасибо
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163465
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Суть hibernate в том, чтобы предоставить объектную структуру во время выполнения транзакции. Для выноса объектов за пределы сервиса лучше копировать их в отдельные DTO.

P.S. вышеизложенное - моё личное имхо
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163491
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-моему в последних версиях идет отказ от hibernate template, в пользу второго варианта. У вас выходит в hibernate template создаётся своя сессия. Вот за пределами template её уже и не видно.
Если вы уверены что дело в соединениях, то нужно натравить транзакции на конкретные классы и методы. Почитайте про аннотацию @Transactional и поставьте её. В пределах метода обозначеного этой аннотацией можно будет загружать ленивые зависимости. А при выходе из такого метода контейнер закроет транзакцию и сессию.
Обратите внимате, что ленивые ассоциации можно загружать сразу же, если они нужны в конкретном методе с помощью FetchMode.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163593
ТимоН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛагманСуть hibernate в том, чтобы предоставить объектную структуру во время выполнения транзакции. Для выноса объектов за пределы сервиса лучше копировать их в отдельные DTO.

P.S. вышеизложенное - моё личное имхо

Не боитесь что придется копировать 1 к 1? Как быть в случаях когда почти все объекты нужны за приделами сервиса?
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163675
snawa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczЕсли вы уверены что дело в соединениях, то нужно натравить транзакции на конкретные классы и методы. Почитайте про аннотацию @Transactional и поставьте её. В пределах метода обозначеного этой аннотацией можно будет загружать ленивые зависимости. А при выходе из такого метода контейнер закроет транзакцию и сессию.


Спасибо за советы. Но мне сделать метод @Transactional не подойдет - коллекциями ведь мне нужно пользоваться извне DAO, причем неизвестно какая пользователю понадобится, и если их загрузить сразу, тогда какой смысл в Lazy инициализации
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163807
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaНо мне сделать метод @Transactional не подойдет - коллекциями ведь мне нужно пользоваться извне DAO
@Transactional можно (и нужно) пользовать и вне DAO.

snawa, причем неизвестно какая пользователю понадобится, и если их загрузить сразу, тогда какой смысл в Lazy инициализации
Сценариев много. В одних нужны зависимости, в других нет. Lazy везде по-умолчанию, чтобы максимально обрезать ассоциации, где они, возможно, не нужны.
В любом случае чтобы догрузить ленивую ассоциацию, нужно держать открытую сессию. Которая вбольшинстве фреймверков 1-к-1 связана с транзакцией.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163808
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно, конечно максимально расширить область видимости сессии с помощью OpenSessionInView, но это скорее заплатка, чем полноценное качественное решение.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163892
Лагман
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТимоН,

вариантов то нет, или отключать lazy или копировать, в чем тогда профит hibernate?
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38163945
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaпричем неизвестно какая пользователю понадобится,
тут надо расшифровать, почему - неизвестно? В ГУИ неизвестно?
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38164446
snawa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Petro123snawaпричем неизвестно какая пользователю понадобится,
тут надо расшифровать, почему - неизвестно? В ГУИ неизвестно?
Да, из ГУИ могут использоваться разные коллекциия - смысла их всех инициализить нету
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38164447
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaДа, из ГУИ могут использоваться разные коллекциия - смысла их всех инициализить нету
Жирный удаленный GUI? Правильно. Все инициализировать не нужно. А вот те которые нужны в каждом конкретном use-case - очень желательно.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38164449
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaPetro123пропущено...
тут надо расшифровать, почему - неизвестно? В ГУИ неизвестно?
Да, из ГУИ могут использоваться разные коллекциия - смысла их всех инициализить нету
верно. Нажали на сисок Городов по всей России - они загрузились.

Значит, когда нужно грузить - вызовется НУЖНЫЙ контроллёр. Так?
Т.е. мы в ГУИ не знаем, но на сервере всегда знаем. Так?
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38164451
snawa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczsnawaНо мне сделать метод @Transactional не подойдет - коллекциями ведь мне нужно пользоваться извне DAO
@Transactional можно (и нужно) пользовать и вне DAO.

snawa, причем неизвестно какая пользователю понадобится, и если их загрузить сразу, тогда какой смысл в Lazy инициализации
Сценариев много. В одних нужны зависимости, в других нет. Lazy везде по-умолчанию, чтобы максимально обрезать ассоциации, где они, возможно, не нужны.
В любом случае чтобы догрузить ленивую ассоциацию, нужно держать открытую сессию. Которая вбольшинстве фреймверков 1-к-1 связана с транзакцией.

Т.е. @Transactional можно помечать методы в UI классах, где например сначала вычитывается объект, а потом берется его коллекция? Как-то это не очень с первого взгляда. Или это нормальная практика?
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38164460
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaТ.е. @Transactional можно помечать методы в UI классах, где например сначала вычитывается объект, а потом берется его коллекция? Как-то это не очень с первого взгляда. Или это нормальная практика?
Достаточно трудно угадать что именно у вас за архитектура. Вы даже не сообщили у вас 3-tier или 2-tier.
Обычно дела обстоят так
UI, грубо говоря, запрашиваен данные у Domain Model, а вот Domain Model уже запускает транзакцию, вычитывает все необходимые данные и возвращает их. Дозагрузка данных в UI называется OpenSessionInView и, иногда, практикуется в Web. Хотя у этого подхода есть свои недостатки. В жирном gui такой подход сложно применить. В 3-tier, так вообще не возможно.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38164470
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я бы делил вдругой плоскости.
Есть 10 контролов в ГУИ.
2 варианта:
- без AJAX все 10 грузятся заранее - никакойленивой загрузки. Либо она есть, но при запросе формы контроллёр грузит всё.
- с AJAX 3 контрула подгружаются по клику. Событе отправится в контроллёр и тоже знаем.

Какое вариант - решает БЛ а не программист.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165323
snawa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczsnawaТ.е. @Transactional можно помечать методы в UI классах, где например сначала вычитывается объект, а потом берется его коллекция? Как-то это не очень с первого взгляда. Или это нормальная практика?
Достаточно трудно угадать что именно у вас за архитектура. Вы даже не сообщили у вас 3-tier или 2-tier.
Обычно дела обстоят так
UI, грубо говоря, запрашиваен данные у Domain Model, а вот Domain Model уже запускает транзакцию, вычитывает все необходимые данные и возвращает их. Дозагрузка данных в UI называется OpenSessionInView и, иногда, практикуется в Web. Хотя у этого подхода есть свои недостатки. В жирном gui такой подход сложно применить. В 3-tier, так вообще не возможно.

3-tier, веб-приложение с использованием ZK framework
Поясню немного схему - допустим на UI есть два метода контроллера,
Код: java
1.
2.
3.
4.
5.
ViewController{
    public void fillUserList()
    
    public void fillUserTable()
}



один получает из сервиса список пользователей, чтобы отобразить их фамилии, а другой получает список пользователей, чтобы отобразить их в таблице с колонками "фамилия", "список ролей", список ролей берется из lazy коллекции user.getRoles(). При этом дергается один и тот же метод сервиса UserService.getUsers(), который в свою очередь обращается к UserDAO, примерную реализацию которого я описал выше. Причем во ViewController я не хочу беспокоится о том, загружены данные или нет - просто выполняю user.getRoles() в любом месте.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165336
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawa3-tier, веб-приложение с использованием ZK framework
Причем во ViewController я не хочу беспокоится о том, загружены данные или нет.
Собственно весь вопрос в эти два предложения можно было уложить.
Ой! Что-тут у нас? Не к столу будет сказано OpenSessionInView от ZK:
http://www.zkoss.org/javadoc/latest/zk/org/zkoss/zkplus/hibernate/OpenSessionInViewListener.html

Ну, и для самообразования рекомендую
http://blog.frankel.ch/the-opensessioninview-antipattern
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165357
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaво ViewController я не хочу беспокоится о том, загружены данные или нет
только что мы не знали, где у нас какие свойство нужны. Теперь [внезапно] все мы прекрасно знаем: в fillUserList() нам нужны только имена, в fillUserTable нам нужны роли. Спрашивается, почему бы не фетчить что надо, там где это надо.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165482
snawa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczsnawa3-tier, веб-приложение с использованием ZK framework
Причем во ViewController я не хочу беспокоится о том, загружены данные или нет.
Собственно весь вопрос в эти два предложения можно было уложить.
Ой! Что-тут у нас? Не к столу будет сказано OpenSessionInView от ZK:
http://www.zkoss.org/javadoc/latest/zk/org/zkoss/zkplus/hibernate/OpenSessionInViewListener.html

Ну, и для самообразования рекомендую
http://blog.frankel.ch/the-opensessioninview-antipattern

про OpenSessionInView слышал, но в основном негатив. Типа используйте, но лучше не надо. Неужели нету никакой хорошей практики?

chpashasnawaво ViewController я не хочу беспокоится о том, загружены данные или нет
только что мы не знали, где у нас какие свойство нужны. Теперь [внезапно] все мы прекрасно знаем: в fillUserList() нам нужны только имена, в fillUserTable нам нужны роли. Спрашивается, почему бы не фетчить что надо, там где это надо.

По вашему, в сервисе по работе с юзером, у которого например две lazy коллекции нужно заранее предусмотреть методы
getUsersWithoutInit(), getUsersWithRoles(), getUsersWithOtherCollection(), getUsersWithRolesAndOtherCollection() и т.д. до n! ? Бред кажется
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165507
chpasha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaПо вашему, в сервисе по работе с юзером, у которого например две lazy коллекции нужно заранее предусмотреть методы
getUsersWithoutInit(), getUsersWithRoles(), getUsersWithOtherCollection(), getUsersWithRolesAndOtherCollection() и т.д. до n! ? Бред кажетсяэто разумный компромисс между "тащить все" и "загружать все лениво" потому что ни один из этих подходов не является оптимальным с точки зрения производительности. а с точки зрения удобства программера оба подхода конечно зашибись, в любом случае ничего не надо делать.

по поводу кучи методов - если повторяющиеся запросы достаточно сложны, выделите общую часть с помощью criteria, и в каждом методе добавляй только изменяющийся фетч.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165544
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawa,
Давай хоть один негатив про сессию на окно-форму.
Правильно сказали - нет золотой пули.
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165545
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
snawaПо вашему, в сервисе по работе с юзером, у которого например две lazy коллекции нужно заранее предусмотреть методы getUsersWithoutInit(), getUsersWithRoles(), getUsersWithOtherCollection(), getUsersWithRolesAndOtherCollection() и т.д. до n! ? Бред кажется
В среднем, хватает 2х-3х вариантов: загрузить одного юзера, но со всеми зависимостями; загрузить список без зависимостей; загрузить список с какими-то конкретными зависимостями.
У вас в системе не будет 100500 вариантов показа списка пользователей.
Ну, и на крайний случай, если таки надо 100500 вариантов (что само по себе подозрительно), то всегда можно из сервиса, в DAO передать список свойств, для которых нужен Eager Fetch.
Код: java
1.
2.
3.
4.
5.
6.
7.
List<User> getUsers(String ... fetchProperties){
     ...
     for(String property : fetchProperties){
        criteria.setFetchMode(property, FetchMode.JOIN);
     }
     ...
}


Есть, правда, нюанс, что JOIN не всегда, подходит, иногда таки нужен Select, но это уже детали реализации классов User/UserDAO
...
Рейтинг: 0 / 0
Spring+Hibernate вопрос о работе с сессиями в DAO объектах
    #38165552
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowicz,
Да. Я думаю, вариантов будет не больше чем контролов в окне форме.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring+Hibernate вопрос о работе с сессиями в DAO объектах
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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