0

i have a multi-tenant application and i need to change the schema name at runtime so it is gonna be shared DB seperate schema SaaS design.

because creating an EntityManagerFactory is very expensive, i would like to create the EMF application-scoped and specify the schema before every DB calls after initiating the EntityManger. i am using Postgresql 8.1 and because Postgesql doesn't support schema selection at setting up the DB connection, i thought the only way to query from tables for different schemas is querying 'SET search_path = "my.schema"' before making the required DB calls.

i have tried;

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

i have got an exception saying 'java.lang.IllegalStateException: You cannot call executeUpdate() on this query. It is the incorrect query type'

i am using eclipselink as PersistenceProvider and glassfish as application manager

is there anyway i can get this done ?

i am open to any suggesstions if there is a better way of accomplishing this

thanks in advance

4

1 回答 1

2

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

ALTER USER thetenant SET search_path = 'thetenant';

如果您还:

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

您将在更大程度上将用户彼此隔离,尽管他们仍然会看到pg_catalog和中的内容INFORMATION_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 版本?

于 2012-05-29T08:46:53.677 回答