【问题标题】:Can Spring's HibernateTransactionManager apply to non-beans?Spring 的 HibernateTransactionManager 可以应用于非 bean 吗?
【发布时间】:2011-12-23 16:56:34
【问题描述】:

简短的问题:我如何(或有可能)在 Spring 中未声明为 bean 的类中使用 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 是 Spring bean(见下文),但 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 代理以插入事务建议,例如 here。但据我所知,这些代理只有在我将类定义为 bean 时才适用,对吧?

  • 我想我也可以使用AspectJ,例如&lt;tx:annotation-driven mode="aspectj"/&gt;,但这似乎需要我使用不同的类加载器,由于各种原因,我不能这样做(需要更改为Tomcat,而不是只是我的网络应用程序......我认为)。见here

  • 我真的不想使用 OpenSessionInView,因为我不太喜欢后端事务发生在服务层之外的想法。

所以,我被难住了。有没有人有任何想法?我尝试过的其中一件事应该已经奏效了吗? (可能是我搞砸了。)

提前致谢。

【问题讨论】:

  • ?
  • 应该是 ,对不起。

标签: hibernate spring spring-transactions


【解决方案1】:

不需要将实体(FooImpl)声明为spring bean。你需要这个

<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>

查看此example

【讨论】:

  • 应该或不应该将 FooImpl 声明为 bean?现在它不是一个 bean(FooManagerImpl 是)。谢谢。
猜你喜欢
  • 2021-09-03
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 2011-02-23
  • 2017-06-20
  • 1970-01-01
相关资源
最近更新 更多