【问题标题】:eclipselink change schema at EntityManager callbackseclipselink 在 EntityManager 回调中更改架构
【发布时间】:2012-06-03 09:20:26
【问题描述】:

我有一个多租户应用程序,我需要在运行时更改架构名称,以便共享数据库独立架构SaaS 设计。

因为创建 EntityManagerFactory 非常昂贵,我想创建 EMF 应用程序范围并在启动 EntityManger 后每个 DB 调用之前指定架构。我正在使用 Postgresql 8.1,因为 Postgesql 在设置数据库连接时不支持模式选择,我认为从表中查询不同模式的唯一方法是查询 'SET search_path = " my.schema"' 在进行所需的数据库调用之前。

我试过了;

StringBuilder sb = new StringBuilder();                
sb.append("SET search_path TO my.schema");            
entityManager_.createNativeQuery(sb.toString()).executeUpdate();

我有一个异常说'java.lang.IllegalStateException:你不能在这个查询上调用executeUpdate()。这是不正确的查询类型'

我使用 eclipselink 作为 PersistenceProvider 和 glassfish 作为应用程序管理器

有没有我可以完成的?

如果有更好的方法来实现这一点,我愿意接受任何建议

提前致谢

【问题讨论】:

  • 进展如何?你还在吗?

标签: postgresql eclipselink glassfish-3 saas multi-tenant


【解决方案1】:

由于您使用的是租户模式,您是否还使用租户特定的数据库登录角色(用户 ID)?如果是这样,您可以将默认搜索路径绑定到您的用户:

ALTER USER thetenant SET search_path = 'thetenant';

如果你也:

REVOKE ALL ON SCHEMA thetenant FROM public;
GRANT ALL ON SCHEMA thetenant TO tenant;

您将在更大程度上将用户彼此隔离,尽管他们仍会看到 pg_catalogINFORMATION_SCHEMA 中的内容。

这要求您为每个租户使用一个登录角色。在使用连接池的情况下,这可能很困难,因为 Java 连接池通常不能切换池连接的用户 ID,并且必须为每个用户 ID 保留一个池。 PostgresSQL 的SET SESSION AUTHORISATION 语句可能很有用,它允许您以单个主用户身份登录,然后切换到执行特定工作所需的用户,但我不知道是否有任何Java 池直接支持它。您可以使用外部连接池,如 PgBouncer 和 PgPool-II,它们可以识别 SET SESSION AUTHORISATION,或者查看是否有任何方法可以编写拦截器,以便在连接从池中签出时发出 SET SESSION AUTHORISATION,并且RESET SESSION AUTHORISATION 当他们重新登记入住时。

即使您不能使用基于角色的访问,我也会对您的搜索路径尝试相同的方法:看看您是否可以在连接池程序的帮助下通过在连接从池中签出时捕获连接来做到这一点对于一项任务,并且在发布时重新签入。但是,如何执行此操作将取决于连接池,您可能不想深入了解其中的细节。

顺便说一句,你到底为什么要使用这样一个史前版本的 PostgreSQL?

我不知道为什么 EclipseLink 拒绝你的命令。从表面上看,它看起来很合理。你也在使用其他东西的古代版本吗?您使用的是哪个 Glassfish 和 EclipseLink 版本?

【讨论】:

  • 这里有 8.1 版本的文档postgresql.org/docs/8.1/static/…
  • 目前,我没有特定于租户的数据库登录角色,唯一的数据库用户是“postgres”,稍后将不得不实现它。我将尝试将 Postgresql 升级到 v9.*,但我需要找出导致问题的原因。我认为这是 eclipselink 设置数据库连接的方式,因为在命令行上“SET search_path”按预期工作。我尝试在开始事务后和启动 EM 后进行此 DB 调用,但均未成功,并且异常在上面。除了 PG,我使用的是最新版本的工具。数据库升级后我会更新帖子,谢谢
  • 当您说“除了 Pg”时,您是否包括 PgJDBC?即,您使用的是古老的 PgJDBC,还是使用 9.1-902 JDBC 4?顺便说一句,您真的应该指定确切的版本,因为当其他人在 6 个月后查看这个问题时,“当前”现在还不清楚。
  • 我使用的是 9.1-902 JDBC4 驱动程序,所以除了 8.1 的 PG 服务器之外,我使用的每个工具都是最新的。 Eclipselink 2.3、glassfish 3.1 和 JPA 2.0。因为数据库服务器迁移不是那么容易,我不认为问题是我没有升级它,但如果我想做的对新版本的 PG 是可行的,我会升级它并分享结果,感谢您的回答
  • 酷。从 8.1 开始,数据库更新并不容易,你是对的。删除隐式转换为文本时会遇到特殊问题。 postgresql.org/docs/8.3/static/release-8-3.htmldepesz.com/2008/05/05/…petereisentraut.blogspot.com.au/2008/03/…wiki.postgresql.org/wiki/Version_History
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-31
  • 2022-10-14
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
  • 2017-11-26
相关资源
最近更新 更多