JSF中的Spring事务

时间:2012-03-23 18:28:11

标签: spring hibernate jsf-2 spring-transactions

使用Spring 3.1,Mojarra,Hibernate

的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中处理事务?

2 个答案:

答案 0 :(得分: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;
  }

答案 1 :(得分:0)

更好地采用分层架构服务和DAO层,直接处理托管bean中的事务会违背类的单一责任原则的目的。

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

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

这样事情更易于管理,可维护和可测试。模拟服务层,测试数据持久性的DAO和视图层的受管Bean。

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

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

希望这会有所帮助!!!!!