如何配置hibernate以使用特定于上下文的连接信息?

时间:2009-04-23 22:18:31

标签: java hibernate connection-pooling c3p0

我正在使用Hibernate编写Java SE(注意, Java EE)应用程序,我需要为每个执行线程提供与Hibernate不同的连接。必须汇集这些连接,并且每个连接至少具有不同的身份验证,并且可能具有不同的JDBC URL。连接将被重用(可以从池化要求中推断出来)。

我必须覆盖Hibernate / C3P0 / et的哪些部分?这可以用这些工具完成,还是我需要编写自己的池数据源?

2 个答案:

答案 0 :(得分:1)

这里有两个问题:

  1. 连接不是线程安全的,因此每个线程必须有自己的连接。由于您正在使用Hibernate,您的应用程序看到的实际上是从SessionFactory获取的Session。要使用它,可以调用SessionFactory#getCurrentSession()方法,并在hibernate.cfg.xml中配置当前会话上下文:
    <property name="current\_session\_context\_class">thread</property>
    如果你在hibernate.cfg.xml中正确配置了线程池(使用c3po或任何你喜欢的池化机制),那么每个线程都将从该池获得连接。
  2. 要维护应用程序可能需要使用的多个数据源,您需要为要访问的每个JDBC URL配置单独的SessionFactory。在您的应用程序中,您需要使用SessionFactory选择一些方法来选择(例如“客户端ID”),使用此方法可以管理Map中的每个SessionFactory实例或某些数据结构(在Java中) EE应用程序,您将从JNDI获得参考。
  3. 总结(并概括),基本上SessionFactory本质上是围绕DataSource(和话务员连接池)的巨大包装器。它是只读的(因此是线程安全的),重量级和静态的,构造一次,并且知道它对给定DataSource所需的一切。

    另一方面,会话本质上是一个围绕Connection的轻量级包装器。它不是线程安全的,通常是短暂的,并且打算被使用然后被丢弃。

    希望这有帮助!

答案 1 :(得分:1)

我认为最好的做法是为每个数据源创建一个SessionFactory,并且可能有汇集连接 - 这就是他的答案中建议的eqbridges。

现在,Hibernate确实有一个ConnectionProvider挂钩,所以我想你可以编写一个实现,它会将Connection返回到不同的数据源,具体取决于当前的执行线程和一些其他参数。从理论上讲,您可以拥有一个SessionFactory实例,该实例将使用由自定义ConnectionProvider实现提供的不同数据库的不同连接。但是,一个SessionFactory包含相当多的数据,然后在为一个工作单元打开Session时,Hibernate会在内部使用该数据。另外,还有与之关联的二级缓存。

不幸的是,工厂和Session你打开它的行为将如何面对这样一个提供者是任何人的猜测。这对我来说感觉像是一个黑客,我怀疑它曾被认为是SessionFactory的可行用例。它可能导致各种各样的,可能非常微妙的错误或数据损坏。

另一方面,请务必准确衡量创建多个SessionFactories的成本 - 它可能没有您想象的那么高。请务必将其与仅打开所需JDBC连接的成本进行比较。我不知道你可能得到什么样的结果,但我认为你应该在采用更多的hackish解决方案之前确定性能。