Upgrading Hibernate 3.3.2 to Hibernate 4.0.0

12 篇文章 0 订阅

As you may know, JBoss AS 7 is incredible fast and low-memory, and it comes with Hibernate 4.0.0 by default. Since AS 7.0.1, it is easy for you to support both Hibernate 3.x and Hibernate 4.0.0 under JBoss AS, thanks to the modular classpath here. If you want to run Hibernate 3.x under AS7 along with Hibernate 4, you should check out this blog entry and this documentation.

In RiftSaw 3 development, we are taking this opportunity to upgrading its JPA layer from JPA 1.0 to JPA 2.0, as JPA 2.0 is back compatible, it shouldn't be an big issue. However, we've implemented the ConnectionProvider and TransactionManagerLookup interfaces, since we've created the Datasource and TransactionManager on our own, we need to implement these two interfaces to ask Hibernate to use our own one.

In Hibernate 4.x, the whole package has been split into three categories, API/Impl/SPI. So the ConnectionProvider class has been re-packaged at: org.hibernate.service.jdbc.connections.spi.ConnectionProvider, if you see the internal implementation of this, you would also notice that it also implements the Configurable and Stoppable. The Configurable interface allows you to access to the Hibernate's properties, which is kept as Map. It is much like Spring's BeanNameAware interface, where you get to access to the BeanName. So below is the code snippet that I used for my ConnectionProvider.

public class DataSourceConnectionProvider implements ConnectionProvider, Configurable, Stoppable  {

  private Properties _props;

  private boolean available = true;

  public DataSourceConnectionProvider() {
  }

  @SuppressWarnings( {"unchecked"})
  public void configure(Map properties) {
     _props = new Properties();
     _props.putAll(properties);
  }

  public Connection getConnection() throws SQLException {
    if (!available) {
        throw new HibernateException( "Provider is closed!" );
    }
    Connection c = HibernateUtil.getConnection(_props);
    DbIsolation.setIsolationLevel(c);
    return c;
  }

  public void closeConnection(Connection con) throws SQLException {
    con.close();
  }

  public boolean supportsAggressiveRelease() {
    return true;
  }

  public boolean isUnwrappableAs(Class unwrapType) {
        return ConnectionProvider.class.equals(unwrapType) ||
                DataSourceConnectionProvider.class.isAssignableFrom(unwrapType);
  }

  @SuppressWarnings( {"unchecked"})
  public  T unwrap(Class unwrapType) {
        if (ConnectionProvider.class.equals(unwrapType) ||
                DataSourceConnectionProvider.class.isAssignableFrom(unwrapType)) {
            return (T) this;
        } else {
            throw new UnknownUnwrapTypeException( unwrapType );
        }
  }

  public void stop() {
    available = false;
  }
}

For the TransactionManagerLookup interface, you would get WARN saying this API has been deprecated ( I believe it has been deprecated before 4.x, but I didn't get a chance to upgrade it until now), we should implement the org.hibernate.service.jta.platform.spi.JtaPlatform SPI instead, and set it to the 'hibernate.transaction.jta.platform' property. Instead of having a class that implement the JtaPlatform SPI directly, I've subclassed it from the AbstractJtaPlatform class, so that I've only needed to override two interfaces. Below is the code snippet for my custom JtaPlatform impl.

/**
 *
 * uses {@link HibernateUtil} to obtain the JTA {@link TransactionManager} object.
 *
 * @author Jeff Yu
 *
 */
public class OdeJtaPlatform extends AbstractJtaPlatform {

    private Properties properties = new Properties();

    public void configure(Map configValues) {
        super.configure(configValues);
        properties.putAll(configValues);
    }

    @Override
    protected TransactionManager locateTransactionManager() {
        return HibernateUtil.getTransactionManager(properties);
    }

    @Override
    protected UserTransaction locateUserTransaction() {
        throw new UnsupportedOperationException("locateUserTransaction is not supported. Use the locateTransactionManager instead.");
    }

}

And then when you create your entityManagerFactory, remember to pass the following properties in.

props.put(Environment.CONNECTION_PROVIDER, DataSourceConnectionProvider.class.getName());
props.put(Environment.JTA_PLATFORM, OdeJtaPlatform.class.getName());

Done, the custom ConnectionProvider and JtaPlatform implementation should be all set now.

Hope this will help you do the Hibernate upgrade at some point. Here, I'd like to thanks Strong Liu to send the helpful links to me on this upgrading. :-)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值