Короткий вопрос: как я могу (или можно) использовать диспетчер транзакций Spring в классах, которые не объявлены как бины в Spring?
Подробности ... У меня есть приложение, использующееSpring 3 и Hibernate 3.6, и два таких класса:
public class FooManagerImpl implements FooManager {
@Override
@Transactional
public Foo getFoo(int id) {
Session s = sessionFactory.getCurrentSession();
// do some query
return foo;
}
}
FooManagerImpl
- это bean-компонент Spring (см. Ниже), а FooImpl
- нет.FooImpl
имеет отношения родитель / потомок с третьим классом, Bar
, который также является сущностью (это то, где вещи ломаются).
@Entity
@Table(name = "foo_table")
public class FooImpl implements Foo {
private List<Bar> bars;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SELECT)
@JoinColumn(name = "foo_id", referencedColumnName = "foo_id")
public List<Bar> getBar() {
return this.bars; // Bar is also an entity
}
public void addBar(Bar b) {
this.bar.add(b);
}
}
И соответствующие части из конфигурации Spring:
<tx:annotation-driven />
<jee:jndi-lookup id="fooDatasource" jndi-name="fooDatasource" />
<bean id="fooSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="fooDatasource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
</props>
</property>
<property name="packagesToScan">
<value>com.foo</value>
</property>
</bean>
<bean id="fooTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="fooSessionFactory" />
<qualifier value="ec" />
</bean>
<bean id="fooManager" class="com.foo.model.FooManagerImpl">
<property name="sessionFactory" ref="fooSessionFactory" />
</bean>
Теперь, насколько я понимаю, при вызове FooImpl.addBar(Bar)
Hibernate будет пытаться сохранить изменения, которые завершаются неудачей, поскольку нет привязанной транзакции.Там нет ограничения TX, потому что Spring не использует прокси ни для одного из методов в FooImpl
, потому что это не bean-компонент.Это правильная оценка?Есть ли способ, которым я могу сделать эту работу?
Решения, которые я нашел до сих пор, но это, кажется, не совсем работает (или я не могу заставить их работать):
Настройте прокси-сервер AOP для вставки транзакционного совета, например здесь .Но, насколько я могу судить, эти прокси будут применяться только в том случае, если я определил класс как бин, верно?
Я думаю, что я также могу использовать AspectJ, например <tx:annotation-driven mode="aspectj"/>
, но это, кажется, требует, чтобы я использовал другой загрузчик классов, который по разным причинам я не могу сделать (требует изменения в Tomcat, а не только в моем веб-приложении ... я думаю).См. здесь .
На самом деле я не хочу использовать OpenSessionInView, потому что мне не очень нравится идея внутренних транзакций, происходящих вне уровня обслуживания.
Итак, я в тупике.У кого-нибудь есть какие-либо идеи?Должна ли одна из вещей, которые я попробовал, уже сработала?(Возможно я облажался.)
Заранее спасибо.