java - 使用 hibernate 参数设置 Postgresql 架构

标签 java postgresql hibernate

我有一个 Multi-Tenancy 应用程序,使用架构来分隔租户。我的连接池不支持开箱即用的 Multi-Tenancy (Dropwizard) - 因此我尝试在检索时手动设置租户的架构。但是,我收到 SQL 语法错误。

代码:

NativeQuery fpq = this.getSessionFactory()
                          .getCurrentSession()
                          .createNativeQuery("SET schema=?");
fpq.setParameter(1, tenantSchema);
fpq.executeUpdate();

错误:

DEBUG org.hibernate.SQL: SET schema=?
TRACE org.hibernate.type.descriptor.sql.BasicBinder: binding parameter [1] as [VARCHAR] - [myapplication_client1]
WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper: SQL Error: 0, SQLState: 42601
ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper: ERROR: syntax error at or near "$1"
  Position: 12

我还尝试了 "SET search_path=?""SET search_path TO ?" ,结果相同。这看起来很简单,我做错了什么? tenantSchema 变量是使用不可信的字符串生成的,因此正确构建参数而不是手动连接 SQL 非常重要。

更新:通过调试器,我已经验证 Hibernate 是否正确地将语句转换为 SET schema 'myapplication_client1' - 但它仍然失败,我不知道为什么。它肯定与 setParameter 有关,因为如果我对其进行硬编码,查询就可以正常运行。

最佳答案

您不能将标识符作为预准备语句中的参数传递。模式名称是一个标识符,就像表名称一样,您也不能执行 select * from ?

您必须将参数连接到您的查询:

NativeQuery fpq = this.getSessionFactory()
                          .getCurrentSession()
                          .createNativeQuery("SET schema=" + tenantSchema);
fpq.executeUpdate();

由于这是来自“不受信任”来源的参数,因此您需要在执行此操作之前验证它是否正确。一种简单的方法是使用 DatabaseMetaData.getSchemas() 检索所有架构并验证参数是否为其中之一。

<小时/>

不相关:

Hibernate is correctly converting the statement to SET schema 'myapplication_client1'

不,Hibernate 不会转换任何内容。这正是 Postgres JDBC 驱动程序实现 PreparedStatement.toString() 方法的方式。这并不意味着它是发送到数据库的查询。 toString() 方法仅用于调试目的(例如用于日志记录目的)

关于java - 使用 hibernate 参数设置 Postgresql 架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43382764/

相关文章:

java - 使用 java.util.logging.Logger 时如何将日志写入文本文件

java - 如何在 Apache Tomcat 服务器中保护我的代码?

java - Spring 通用 Hibernate DAO

java - 标准多对多 Hibernate

sql - 仅在 PostgreSQL 中按月分组查询?

mysql - 同一实体的多个表示正在合并错误

JavaFX ObjectBinding不会触发computeValue,绑定(bind)属性不会改变

带参数的 Java Reflection 私有(private)方法最好的方法?

javascript - 在 Node.js 和 Knex 中向现有表添加列

postgresql - 在窗口函数中使用计算列名