如何配置 hibernate 以使用特定于上下文的连接信息?
我正在使用 Hibernate 编写 Java SE(注意,不是 Java EE)应用程序,并且我需要为每个执行线程提供与 Hibernate 的不同连接。 这些连接必须集中在一起,并且每个连接至少具有不同的身份验证,并且可能具有不同的 JDBC URL。 连接将被重新使用(可以从池化要求推断出)。
我必须覆盖 Hibernate/C3P0/et al 的哪些部分? 可以使用这些工具来完成此操作,还是我需要编写自己的池数据源?
I'm writing a Java SE (Note, not Java EE) application using Hibernate, and I need to provide a different connection to Hibernate for each thread of execution. These connections must be pooled, and each one has at the very least different authentication and, possibly, a different JDBC URL. The connections will be re-used (as can be inferred from the pooling requirement).
What parts of Hibernate/C3P0/et al do I have to override? Can this be accomplished with those tools, or do I need to write my own pooling data source?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为最好的做法是为每个数据源创建一个 SessionFactory ,并可能使用池连接 - 这就是 eqbridges 在他的答案中建议的。
现在,Hibernate 确实有一个
ConnectionProvider
钩子,所以我想您可以编写一个实现,根据当前的执行线程和一些额外的操作,将Connection
返回到不同的数据源参数。 理论上,您可以拥有一个SessionFactory
实例,该实例将使用由您的自定义ConnectionProvider
实现提供的与不同数据库的不同连接。 但是,一个 SessionFactory 保存相当多的数据,然后在为工作单元打开 Session 时,Hibernate 在内部使用这些数据。 另外,还有一个与之相关的二级缓存。不幸的是,面对这样的提供者,您打开的工厂和会话将如何表现,谁也说不准。 对我来说,这感觉像是一种黑客攻击,而且我怀疑它是否被认为是
SessionFactory
的可行用例。 它可能会导致各种(可能是非常微妙的)错误或数据损坏。另一方面,请务必准确测量创建多个 SessionFactories 的成本 - 它可能没有您想象的那么高。 请务必将其与简单打开所需 JDBC 连接的成本进行比较。 我不知道您可能会得到什么样的结果,但我认为您应该在采用更黑客的解决方案之前确定性能。
I think the best course of action would be creating a
SessionFactory
for each data source, with possibly pooled connections - that's what's eqbridges suggested in his answer.Now, Hibernate does have a
ConnectionProvider
hook, so I suppose you could write an implementation that would returnConnection
s to different data sources, depending on current thread of execution and some additional parameters. Theoretically, you can then have oneSessionFactory
instance, which will be using different connections to different databases, supplied by your customConnectionProvider
implementation. But, oneSessionFactory
holds quite a bit of data, and that data is then used by Hibernate internally, when opening aSession
for a unit of work. Plus, there's a second-level cache associated with it as well.Unfortunately, how will the factory and
Session
s you open from it behave in the face of such a provider is anybody's guess. It feels like a hack to me, and I doubt it was ever considered a viable use-case for aSessionFactory
. It can possibly lead to all kinds of, possibly very subtle, bugs or data corruption.On another note, be sure to exactly measure the cost of creating multiple
SessionFactories
- it may not be as high as you think. Be sure to compare that with the cost of simply opening the needed JDBC connections. I don't know what kind of results you might get, but I think you should be sure about performance before you resort to more hackish solutions.这里有两个问题:
如果您在 hibernate.cfg.xml 中正确配置了线程池(使用 c3po 或您喜欢的任何池机制),那么每个线程都会从该池获得一个连接。
总结(和概括),基本上 SessionFactory 本质上是数据源(以及附带的连接池)的巨大包装。 它是只读的(因此是线程安全的)、重量级的和静态的,构造一次,并且知道给定数据源所需的一切。
另一方面,会话本质上是连接的轻量级包装。 它不是线程安全的,通常是短暂的,并且打算使用然后丢弃。
希望这可以帮助!
You have two questions here:
If you've properly configured thread pooling (using c3po or whatever pooling mechanism you favor) in hibernate.cfg.xml, then each thread will get a connection from that pool.
To summarize (and generalize), basically a SessionFactory is essentially huge wrapper around a DataSource (and attendant connection pool). It is read-only (and hence thread safe), heavyweight and static, constructed once, and knows everything it needs to about a given DataSource.
A Session, on the other hand is essentially a lightweight wrapper around a Connection. It is not thread safe, often short-lived, and intended to be used and then thrown away.
Hope this helps!