Hibernate + Spring: injections to entities?
От: Дм.Григорьев  
Дата: 21.02.08 05:49
Оценка:
Люююдиии!!!
Ах да, сначала всем привет.

Есть ли способ заставить Hibernate создавать экземпляры entities, используя Spring IoC (prototype scope), или какой другой (желательно блин удобный) способ инъектить в entities зависимости? Ну просто достало уже это спагетти.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re: Hibernate + Spring: injections to entities?
От: vb-develop  
Дата: 21.02.08 05:57
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Люююдиии!!!

ДГ>Ах да, сначала всем привет.

ДГ>Есть ли способ заставить Hibernate создавать экземпляры entities, используя Spring IoC (prototype scope), или какой другой (желательно блин удобный) способ инъектить в entities зависимости? Ну просто достало уже это спагетти.


Тоже одно время интересно было из любопытства. Но потом подумал, что инкапсулировать логику в модель не очень хорошо в моем конкретном случае будет. У тебя как задача стоит?
Re[2]: Hibernate + Spring: injections to entities?
От: Дм.Григорьев  
Дата: 21.02.08 06:13
Оценка:
Здравствуйте, vb-develop, Вы писали:

VD>Тоже одно время интересно было из любопытства. Но потом подумал, что инкапсулировать логику в модель не очень хорошо в моем конкретном случае будет. У тебя как задача стоит?


Да просто ради удобства. Ну вот например: если у объекта-списка дофига дочерних объектов-элементов, которые все сразу не загрузишь, и стоит задача постраничного вывода. Мечтается что-то вроде следующего:

class SomeList {
    public void toXML(XElement e, int pageSize, int pageNo) {
        // output album's properties
        
        // getItems() requires DB access, i.e. session injection.
        Iterator<SomeItem> i = getItems(pageSize, pageNo);
        while (i.hasNext()) {
            i.next().toXML(XElement.addChild("r"));
        }
    }
}
while (i.hasNext()) {
}


Нынче приходится выносить метод toXML() в контроллер-синглетон, что выглядит довольно коряво.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[3]: Hibernate + Spring: injections to entities?
От: vb-develop  
Дата: 21.02.08 07:14
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Нынче приходится выносить метод toXML() в контроллер-синглетон, что выглядит довольно коряво.


В контроллере доступ к сессии есть? имхо класс контроллера в этом случае работу сервиса выполняет. Хотя если приложение небольшое, можно и без сервисов.
Injections to entities: нашёл, но не работает. :(
От: Дм.Григорьев  
Дата: 21.02.08 07:40
Оценка:
ДГ>Есть ли способ заставить Hibernate создавать экземпляры entities, используя Spring IoC (prototype scope), или какой другой (желательно блин удобный) способ инъектить в entities зависимости?

Нашёл в Spring 2.5 Reference, Chapter 6.8.1 "Using AspectJ to dependency inject domain objects with Spring". Правда там без полноценных примеров, а всю главу читать времени нет.

Добавлено в applicationContext.xml:
<context:spring-configured />


Entity.java:
@Configurable(autowire=Autowire.BY_TYPE, dependencyCheck=true)
public class Entity {
    @Autowired
    protected Controller controller;
}


Дополнительные либы на classpath Tomcat положил, на отсутствие классов при запуске и работе не ругается. Но controller всегда null.

Подскажите плиз, что не так?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re: Injections to entities: работает, но в логах мусор.
От: Дм.Григорьев  
Дата: 21.02.08 08:15
Оценка:
Ещё добавлено:
<context:load-time-weaver/>


В META-INF/context.xml приложения добавлено:
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader" />


Всё работает(!), но при инициализации приложения в логи вылетает длиннющая простыня с ошибками следующего (и не только) вида:

[StandardClassLoader@1c5f743] warning can't find type XXX whilst determining signatures of call or execution join point for YYY.M(), this may cause a pointcut to fail to match at this join point
when weaving type YYY
when weaving classes
when weaving


Как бы загасить весь этот вывод?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[2]: Injections to entities: работает, но в логах мусор.
От: vb-develop  
Дата: 21.02.08 08:39
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Всё работает(!), но при инициализации приложения в логи вылетает длиннющая простыня с ошибками следующего (и не только) вида:


ДГ>

ДГ>[StandardClassLoader@1c5f743] warning can't find type XXX whilst determining signatures of call or execution join point for YYY.M(), this may cause a pointcut to fail to match at this join point
ДГ>when weaving type YYY
ДГ>when weaving classes
ДГ>when weaving


ДГ>Как бы загасить весь этот вывод?


Dependency check отключи.
Re[3]: Injections to entities: работает, но в логах мусор.
От: Дм.Григорьев  
Дата: 21.02.08 09:00
Оценка:
Здравствуйте, vb-develop, Вы писали:

VD>Dependency check отключи.


А это где и как?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[4]: Injections to entities: работает, но в логах мусор.
От: vb-develop  
Дата: 21.02.08 09:11
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Здравствуйте, vb-develop, Вы писали:


VD>>Dependency check отключи.


ДГ>А это где и как?


Entity.java:
@Configurable(autowire=Autowire.BY_TYPE, dependencyCheck=false)
Re[5]: Injections to entities: работает, но в логах мусор.
От: Дм.Григорьев  
Дата: 21.02.08 09:17
Оценка:
Здравствуйте, vb-develop, Вы писали:

VD>Entity.java:

VD>@Configurable(autowire=Autowire.BY_TYPE, dependencyCheck=false)

А, это не помогает. Я там уже вообще все параметры из аннотации убрал. Пробовал aop.xml состряпать, тоже не помогло (похоже он вообще не цепляется):

<?xml version="1.0" encoding="UTF-8"?>
<aspectj>
    <weaver>
        <include within="ru.dimgel.XXX.*"/>
    </weaver>
</aspectj>
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[6]: Injections to entities: работает, но в логах мусор.
От: vb-develop  
Дата: 21.02.08 09:19
Оценка:
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Здравствуйте, vb-develop, Вы писали:


VD>>Entity.java:

VD>>@Configurable(autowire=Autowire.BY_TYPE, dependencyCheck=false)

ДГ>А, это не помогает. Я там уже вообще все параметры из аннотации убрал. Пробовал aop.xml состряпать, тоже не помогло (похоже он вообще не цепляется):



Что у тебя в applicationContext.xml написано?
Re[7]: Injections to entities: работает, но в логах мусор.
От: Дм.Григорьев  
Дата: 21.02.08 09:27
Оценка:
Здравствуйте, vb-develop, Вы писали:

VD>Что у тебя в applicationContext.xml написано?


    <!-- DB-related stuff ... -->
    
    <context:load-time-weaver/>
    <context:spring-configured />
    <context:annotation-config />
    <context:component-scan base-package="..." />
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re: Injections to entities: нашёл, но не работает. :(
От: danila.master Россия  
Дата: 21.02.08 09:35
Оценка: 12 (1)
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>>Есть ли способ заставить Hibernate создавать экземпляры entities, используя Spring IoC (prototype scope), или какой другой (желательно блин удобный) способ инъектить в entities зависимости?


ДГ>Нашёл в Spring 2.5 Reference, Chapter 6.8.1 "Using AspectJ to dependency inject domain objects with Spring". Правда там без полноценных примеров, а всю главу читать времени нет.


Интересное решение. А на производительность сильно влияет?

Сейчас посмотрел — можно еще сделать без использования аспектов, через Interceptor (хотя это менее универсально). Например:
public class HbnDomainInterceptor extends EmptyInterceptor implements BeanFactoryAware {
        AutowireCapableBeanFactory beanFactory;
    
    public AutowireCapableBeanFactory getBeanFactory() {
        return beanFactory;
    }

    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = (AutowireCapableBeanFactory) beanFactory;
    }

    @Override
    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        // Установка зависимостей
        beanFactory.autowireBeanProperties(entity, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
        return super.onLoad(entity, id, state, propertyNames, types);
    }

}


HbnDomainInterceptor объявлен к контексте spring'а.
Re[2]: Injections to entities: нашёл, но не работает. :(
От: Дм.Григорьев  
Дата: 21.02.08 09:43
Оценка:
Здравствуйте, danila.master, Вы писали:

DM>Интересное решение. А на производительность сильно влияет?


А фиг его знает. Надо полагать, хорошо влияет.

DM>Сейчас посмотрел — можно еще сделать без использования аспектов, через Interceptor (хотя это менее универсально). Например:


Во, спасибо. Это выглядит посимпатичнее. А как его в applicationContext.xml прописать, чтобы сессия его сама цепляла?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[3]: Injections to entities: нашёл, но не работает. :(
От: danila.master Россия  
Дата: 21.02.08 10:15
Оценка: 12 (1)
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Здравствуйте, danila.master, Вы писали:


DM>>Интересное решение. А на производительность сильно влияет?


ДГ>А фиг его знает. Надо полагать, хорошо влияет.


Давно хочу где-нибудь заюзать AspectJ, но потенциальные проблемы с производительностью останавливают. А для необходимых вещей пока хватает Spring AOP.

DM>>Сейчас посмотрел — можно еще сделать без использования аспектов, через Interceptor (хотя это менее универсально). Например:


ДГ>Во, спасибо. Это выглядит посимпатичнее. А как его в applicationContext.xml прописать, чтобы сессия его сама цепляла?


Если SessionFactory создается в spring, то можно просто параметр установить:
    <bean id="entityInterceptor" class="zzz.HbnDomainInterceptor"/>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
        <property name="configLocation" value="classpath:/hibernate.cfg.xml"/>
        <property name="entityInterceptor" ref="entityInterceptor"/>
    </bean>


А так interceptor указывается при создании сессии — sessionFactory.openSession(connection, interceptor).
Re[4]: Injections to entities: нашёл, но не работает. :(
От: dshe  
Дата: 21.02.08 11:19
Оценка: 6 (1) +1
Здравствуйте, danila.master, Вы писали:

DM>>>Интересное решение. А на производительность сильно влияет?


ДГ>>А фиг его знает. Надо полагать, хорошо влияет.


DM> Давно хочу где-нибудь заюзать AspectJ, но потенциальные проблемы с производительностью останавливают. А для необходимых вещей пока хватает Spring AOP.


А какие проблемы с производительностью в AspectJ? Как я понимаю, AspectJ подразумевает inline изменение байткода (который исполняется непосредственно и даже может быть оптимизирован JIT'ом) в то время как Spring AOP — JDK/CGLIB Proxy + Reflection на вызовы методов, что в принципе врядли когда-нибудь будет быстрее. Или я что-то упустил?

Я не советую использовать AspectJ, вариант с Interceptor мне нравится больше (хотя autowire меня настораживает), а еще лучше было бы отвязать зависимость entity бинов от какого-то там контроллера.
--
Дмитро
Re[5]: Injections to entities: нашёл, но не работает. :(
От: Дм.Григорьев  
Дата: 21.02.08 11:30
Оценка:
Здравствуйте, dshe, Вы писали:

D>Я не советую использовать AspectJ, вариант с Interceptor мне нравится больше (хотя autowire меня настораживает),


Уже сделано. С ним меньше и зависимостей, и прочего геморроя.

D>а еще лучше было бы отвязать зависимость entity бинов от какого-то там контроллера.


А зависимость в entities у меня только одна — session factory. Так что тут всё нормально. Гы, пока что.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
http://dimgel.ru/lib.web — thin, stateless, strictly typed Scala web framework.
Re[5]: Injections to entities: нашёл, но не работает. :(
От: danila.master Россия  
Дата: 21.02.08 16:28
Оценка:
Здравствуйте, dshe, Вы писали:

D>Здравствуйте, danila.master, Вы писали:


DM>> Давно хочу где-нибудь заюзать AspectJ, но потенциальные проблемы с производительностью останавливают. А для необходимых вещей пока хватает Spring AOP.


D>А какие проблемы с производительностью в AspectJ? Как я понимаю, AspectJ подразумевает inline изменение байткода (который исполняется непосредственно и даже может быть оптимизирован JIT'ом) в то время как Spring AOP — JDK/CGLIB Proxy + Reflection на вызовы методов, что в принципе врядли когда-нибудь будет быстрее. Или я что-то упустил?


Я имел ввиду немного другое. Spring AOP у нас используется для объектов высокого уровня (DAO, сервисы) — для декларативных транзакций, безопасности и т.п.
А интересно применить AOP на уровне более мелких объектов, например, hibernate entity. Например, настроить валидацию через Oval. Но есть опасения, что если начать активное использование аспектов, это может заметно сказаться на производительности.
На самом деле этот вопрос имеет смысл рассматривать в контексте конкретной задачи.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.