什么"代理" state表示Hibernate Session

时间:2015-01-29 07:40:21

标签: java hibernate orm proxy transactions

我在Jboss网站上看到了关于Hibernate Documentation的这一行。

Because Hibernate can't bind the "current session" to a transaction, 
as it does in a JTA environment, it binds it to the current Java thread
when i do transction demarcation with plain JDBC. 
It is opened when getCurrentSession() is called for the first time, 
but in a "proxied" state that doesn't allow you to do anything except 
start a transaction.

那么,作者究竟是什么意思 “代理状态” 。他们与 代理对象 有什么联系?

1 个答案:

答案 0 :(得分:1)

如果没有JTA,事务管理是通过JDBC Connection的提交/回滚方法完成的。

这意味着您必须将一个JDBC Connection绑定到当前正在运行的Hibernate会话和当前的逻辑事务。

因为将JDBC连接传递给所有Hibernate Session方法将是一个糟糕的设计解决方案,所以您必须使用线程本地存储。

Hibernate具有灵活的CurrentSessionContext,提供以下替代方案:

  • JTASessionContext
  • ManagedSessionContext
  • ThreadLocalSessionContext

因此,如果选择ThreadLocaSessionContext,则底层JDBC连接将绑定到Thread本地存储,并使其可用于当前运行Session的Thread。

如果您使用Spring,则不应该依赖Hibernate TreadLocal上下文,而是使用Spring特定的事务管理支持,该支持通过以下方式实现:

  • SpringJtaSessionContext
  • SpringSessionContext

对于代理状态,Hibernate TreadLocalContext使用Hibernate会话的代理:

protected Session wrap(Session session) {
    final TransactionProtectionWrapper wrapper = new TransactionProtectionWrapper( session );
    final Session wrapped = (Session) Proxy.newProxyInstance(
            Session.class.getClassLoader(),
            SESSION_PROXY_INTERFACES,
            wrapper
    );
    wrapper.setWrapped( wrapped );
    return wrapped;
}

当调用Session.close()方法时,允许当前Session 取消绑定本身形成TreadLocal存储。

// If close() is called, guarantee unbind()
if ( "close".equals( methodName ) ) {
    unbind( realSession.getSessionFactory() );
}