Может ли Spring HibernateTransactionManager применяться к не-бинам? - PullRequest
0 голосов
/ 23 декабря 2011

Короткий вопрос: как я могу (или можно) использовать диспетчер транзакций 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, потому что мне не очень нравится идея внутренних транзакций, происходящих вне уровня обслуживания.

Итак, я в тупике.У кого-нибудь есть какие-либо идеи?Должна ли одна из вещей, которые я попробовал, уже сработала?(Возможно я облажался.)

Заранее спасибо.

1 Ответ

0 голосов
/ 23 декабря 2011

Не нужно объявлять сущность (FooImpl) как пружинный бин.вам нужно это

<bean id="fooSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="fooDatasource" />
    <property name="annotatedClasses">
        <list>
           <value>com.foo.model.FooImpl</value>     // Entity
        </list>
    </property>
    <property name="hibernateProperties">
    <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
    </props>
</property>
<property name="packagesToScan">
    <value>com.foo</value>
</property>

просмотреть пример

...