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

发布于 2024-07-18 02:29:24 字数 238 浏览 4 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自我难过 2024-07-25 02:29:24

我认为最好的做法是为每个数据源创建一个 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 return Connections to different data sources, depending on current thread of execution and some additional parameters. Theoretically, you can then have one SessionFactory instance, which will be using different connections to different databases, supplied by your custom ConnectionProvider implementation. But, one SessionFactory holds quite a bit of data, and that data is then used by Hibernate internally, when opening a Session for a unit of work. Plus, there's a second-level cache associated with it as well.

Unfortunately, how will the factory and Sessions 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 a SessionFactory. 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.

池木 2024-07-25 02:29:24

这里有两个问题:

  1. 连接不是线程安全的,因此每个线程必须有自己的连接。 由于您正在使用 Hibernate,因此您的应用程序看到的实际上是从 SessionFactory 获取的 Session。 要利用此功能,您可以调用 SessionFactory#getCurrentSession() 方法,并在 hibernate.cfg.xml 中配置当前会话上下文:
    <属性名称=“current\_session\_context\_class”>线程

    如果您在 hibernate.cfg.xml 中正确配置了线程池(使用 c3po 或您喜欢的任何池机制),那么每个线程都会从该池获得一个连接。

  2. 要维护应用程序可能需要使用的多个数据源,您需要为每个要访问的 JDBC url 配置一个单独的 SessionFactory。 在您的应用程序中,您需要有一些使用 SessionFactory 进行选择的方法(例如“客户端 ID”),使用它您可以管理 Map 或某种此类数据结构(在 Java 中)中的每个 SessionFactory 实例EE 应用程序,您可以从 JNDI 获得参考)。

总结(和概括),基本上 SessionFactory 本质上是数据源(以及附带的连接池)的巨大包装。 它是只读的(因此是线程安全的)、重量级的和静态的,构造一次,并且知道给定数据源所需的一切。

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

希望这可以帮助!

You have two questions here:

  1. Connections are not thread safe, so each thread must have its own connection. Since you're working with Hibernate, what your application sees is actually a Session obtained from a SessionFactory. To utilize this, you call the SessionFactory#getCurrentSession() method, and configure the current session context in hibernate.cfg.xml:
    <property name="current\_session\_context\_class">thread</property>

    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.

  2. To maintain multiple data sources that the application may need to work with, then you need to configure a separate SessionFactory for each JDBC url you'd like to access. In your application you'll need to have some means of selecting with SessionFactory you'll need to choose (e.g. "client ID"), using this you can manage each of the SessionFactory instances in a Map or somesuch data structure (in a Java EE app you'd get a reference from JNDI).

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文