【问题标题】:Spring Transaction in JSFJSF 中的 Spring 事务
【发布时间】:2012-03-23 18:28:10
【问题描述】:

使用 Spring 3.1,Mojarra,休眠

applicationContext.xml

    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    ... 
    </bean>     

    <tx:annotation-driven  />

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

    <context:component-scan base-package="mypackage"/>

TestBean.java

@Component
@Scope("session")
public class TestBean {

@Autowired private @Getter @Setter HibernateTemplate hibernateTemplate=null;

public String submit(){
    try{
        this.test();
    }catch (RuntimeException ex) {
        FacesUtil.addWarn("Error");
    }

    return null;
}

@Transactional
public String test() {

    Device d1=new Device();
    hibernateTemplate.persist(d1);

    if(1==1)
        throw new RuntimeException("Testing");

    Device d2=new Device();
    hibernateTemplate.persist(d2);
    return null;
}

}

这有效(回滚),但在浏览器中显示异常

<h:commandButton value="Submit" action="#{testBean.test}"/>

试图显示面孔消息,但这会提交 d1

<h:commandButton value="Submit" action="#{testBean.submit}"/>

调用其他 bean 的 (DAO) 事务方法也可以,但我希望在托管 bean 本身中有代码。我应该如何在 JSF 中处理事务?

【问题讨论】:

    标签: spring hibernate jsf-2 spring-transactions


    【解决方案1】:

    如果您出于某种原因希望避免使用,请将事务方法移至另一层或使用TransactionTemplate

      public String test() {
        TransactionTemplate txTemplate = new TransactionTemplate(transactionManager);
    
        try {
          txTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
              // your transactional code here;
            }
          });
        } catch (Exception e) {
          // handle exception here
        }
        return null;
      }
    

    【讨论】:

      【解决方案2】:

      最好采用分层架构Service和DAO层,直接在托管bean中处理事务违背了类单一职责原则的目的。

      托管 Bean 的灵魂目的应该是用于导航处理和数据从视图层到服务层的网关,您可以在其中执行主要业务逻辑或用例,并将数据持久性委托给 DAO 层。

      就发送至 UI 的消息而言,您可以从服务层捕获异常并相应地填充所需的消息。

      通过这种方式,事情更易于管理、可维护和可测试。模拟你的服务层,测试 DAO 的数据持久性和视图层的托管 Bean。

      Spring 使用代理/AOP 来实现神奇的@Transactional,并且更好地为接口编写代码,因为如果您不编写接口代码,即直接代理到接口或 CGLIB 子类进行注入,它有自己的问题。在文档中查找代理设置的标签,以便更好地理解我所说的接口代码的含义。

      注意:HibernateTemplate 被认为是一种反模式,并从 Hibernate 4 中删除,仅支持一个指针,因此如果在 Hibernate 3 上,您可以采取相应的行动。

      希望这有帮助!!!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-21
        • 1970-01-01
        • 2014-07-14
        • 2014-06-05
        • 2015-03-26
        • 2016-05-27
        相关资源
        最近更新 更多