【问题标题】:Spring + Hibernate = "manual" transactions how-toSpring + Hibernate =“手动”事务操作方法
【发布时间】:2012-04-13 22:21:04
【问题描述】:

我的 webapp (Spring3 + Hibernate3) 总是使用带有 @Transactional 注释的服务类和这个配置:

<tx:annotation-driven transaction-manager="transactionManager" />

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

现在...我在 Google AppEngine 上。由于一些我还不知道的讨厌的原因,@Transactional 不起作用。它在 javax.naming 中使用了一些没有被列入白名单的类。最后是:

创建名为“mySessionFactory”的 bean 时出错:后处理 FactoryBean 的对象失败;嵌套异常是 java.lang.SecurityException:无法获取类的成员 org.hibernate.impl.SessionFactoryImpl

请不要问我为什么.... :-\

使用 Spring 的 HibernateTemplate 而不是我的 dao(使用原始会话工厂)解决了这个问题,但我知道它有点过时了。

所以,我想尝试使用手动旧式交易。问题:

  • 在哪里?我想将事务保留在服务层中。
  • 怎么样?

【问题讨论】:

    标签: spring hibernate google-app-engine transactions


    【解决方案1】:

    SessionFactoryImpl 依赖项不在 Google App Engine 白名单中。有很多 Google 热门文章都在讨论它。

    至于“做什么”,你有选择:

    • 依赖于另一个 JPA 提供者

    • 完全不使用 ORM,使用 Spring 的 JdbcTemplate(我最喜欢的)原生化

    • 我不知道为什么你需要使用程序化事务管理,因为 Hibernate 是你问题的根源,但如果你只是想知道如何,这里有一个草稿:

    public class SomeService implements SomeInterface {
    
       private SomeDao thisDaoWrapsJdbcTemplate;
       private PlatformTransactionManager transactionManager;
    
       public void setTransactionManager( PlatformTransactionManager transactionManager ) {
          this.transactionManager = transactionManager;
       }
    
       public void doBusiness( Business: business ) {
    
          TransactionDefinition def = new DefaultTransactionDefinition();
          TransactionStatus status = transactionManager.getTransaction( def );
    
          try {
    
             // do business here
             Money money = Money.LOTS_OF
             ...
             // wire the money in..
             thisDaoWrapsJdbcTemplate.depositLotsOfMoney( money )
    
             transactionManager.commit( status );
    
          } catch ( DataAccessException dae ) {
    
             transactionManager.rollback( status );
             throw dae;
          }
          return;
       }
    

    【讨论】:

    • 首先,谢谢。这是我一直在寻找的答案。你能指出我在 Hibernate 文档中的正确位置(或关于该论点的快速教程)吗?我将在接下来的 cmets 中回答您的问题:
    • 1 和 2) 另一个 JPA 提供程序...你是什么意思?我正在使用谷歌云 SQL。我的 GAE 应用程序可以使用本机 JDBC,但是……我喜欢 ORM,而且 Hibernate 非常有吸引力。你的意思是使用 JPA 而不是 Hibernate?
    • 3) 我需要使用编程事务,因为@Transactional(不知道为什么)在某些部分依赖于 javax.naming。我也尝试使用声明性 (aspectj) tx 配置,但是....同样的例外!找不到类:javax.naming.NamingException。 GAE 团队中没有人在帮助我! :-( 现在,在你的帮助下,我的 DAO 又开始工作了!
    • 鉴于第三条评论(例如DAO is working again),不确定您是否需要上述评论的答案,但它来了:另一个 JPA 提供商我指的是像 Kodo、EclipseLink、DataNucleus 这样的人, OpenJPA 等。但由于您已经让 yours 工作,因此此信息仅用于理论目的。
    • 您可以将回调/函数/等传递给上面的“doBusiness”方法:例如public void doBusiness( Business: business, YourService: service ) { ... try { service.someMethod( business ); tx.commit(status) } ... }。通过这种方式,您可以重用存放在一个地方的事务逻辑。
    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 2011-09-24
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    相关资源
    最近更新 更多