我正在使用 Spring 和 Hibernate 开发一个 Web 应用程序,我非常着迷于让他的应用程序线程安全并能够支持重负载,因此根据我老板的建议,我最终编写了自己的会话和一个会话容器来实现每个请求模式的会话。
您应该删除所有这些代码并改用 Spring/Hibernate API:更少的错误,更少的维护。
我复制粘贴这个 Hibernate GenericDAO(我不能说它是同一件事,因为当时 hibernate 不属于 jboss)并做管道工作,在压力下,一切都很快变得复杂(...)
您可以使用 GenericDao 并使用 Spring 注入所需的东西。
问题 1:Hibernate 生成的 uuid 对于线程环境和避免 StaleObjectException 是否足够安全?
为了严格回答您的问题,以下是参考指南中有关 uuid 生成器的内容:
...
所以我认为它是安全的。但我认为你的StaleObjectException 是无关的(这是另一个问题)。
问题 2:在 threadSafe 场景中使用 hibernate getCurrentSession 的最佳策略是什么(我读过有关 threadlocal 的东西,但没有得到太多理解,所以没有这样做)
最好的策略是直接使用它,sessionFactory.getCurrentSession() 将始终为您提供一个Session,其范围为当前数据库事务,即“上下文会话”。再次引用参考文档:
大多数使用 Hibernate 的应用程序需要
某种形式的“上下文”会话,
给定会话生效的地方
在给定的范围内
语境。但是,跨应用程序
定义什么构成
上下文通常不同;
不同的语境定义不同的
范围为电流的概念。
之前使用 Hibernate 的应用程序
3.0 版倾向于利用
国产ThreadLocal-based
上下文会话,助手类
例如 HibernateUtil,或利用
第三方框架,例如 Spring
或 Pico,它提供
基于代理/拦截的上下文
会议。
(...)
但是,从 3.1 版开始,
后处理
SessionFactory.getCurrentSession()
现在是可插拔的。为此,一个新的
扩展接口,
org.hibernate.context.CurrentSessionContext,
和一个新的配置参数,
hibernate.current_session_context_class,
已添加以允许可插入性
定义的范围和背景
当前会话。
请参阅 Javadocs
org.hibernate.context.CurrentSessionContext
详细讨论界面
它的合同。它定义了一个单一的
方法,currentSession(),通过它
实施负责
跟踪当前上下文
会议。开箱即用,休眠
带有三个实现
这个界面:
-
org.hibernate.context.JTASessionContext:
跟踪当前会话并
由 JTA 事务限定。这
这里的处理与
在较旧的仅 JTA 方法中。看
有关详细信息,请参阅 Javadocs。
-
org.hibernate.context.ThreadLocalSessionContext:
当前会话由线程跟踪
的执行。请参阅 Javadocs
详情。
-
org.hibernate.context.ManagedSessionContext:
当前会话由线程跟踪
的执行。然而,你是
负责绑定和解除绑定
带有静态方法的会话实例
在这堂课上:它不打开,
刷新或关闭会话。
(...)
现在没有必要实现自己的基于ThreadLocal 的解决方案,不要那样做。
问题 3:HIbernateTemplate 是否会采用最简单的解决方案?
好吧,HibernateTemplate 没有被弃用,但不再推荐,我更喜欢实现template-less DAOs:
public class ProductDaoImpl implements ProductDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Collection loadProductsByCategory(String category) {
return this.sessionFactory.getCurrentSession()
.createQuery("from test.Product product where product.category=?")
.setParameter(0, category)
.list();
}
}
SessionFactory 是由 Spring 注入的。我建议阅读 So should you still use Spring's HibernateTemplate and/or JpaTemplate?? 以了解完整的背景以及 Spring 文档中有关 ORM 数据访问的整个部分 13.3. Hibernate。
问题 4:如果您要为生产服务器实现连接池和调整要求,您会选择什么?
嗯……什么?我永远不会实现我的连接池,而是使用我的应用程序服务器中的一个。也许你应该澄清这个问题。
更新: 在生产中,我不会使用 Hibernate 内置连接池,而是将 Hibernate 配置为使用应用程序服务器提供的 JNDI 数据源(以及应用程序服务器连接池)。来自文档:
...
这是一个示例 hibernate.properties 文件,用于应用服务器提供的 JNDI 数据源:
hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
从 JNDI 数据源获得的 JDBC 连接将自动参与应用服务器的容器管理事务。