Hibernate @Formula 不包含 Schema
Hibernate @Formula doesn't include Schema
我有一个带有 属性 @Formula 的实体,如下所示:
@Entity
@Table(name = "areasAuxiliar")
public final class AreaAuxiliar implements Serializable {
@Id
@Column(name = "idArea")
private Integer idArea;
@Formula("RUTAAREA(idArea)")
private String ruta;
当我将我的休眠配置为指向 Oracle 数据库时我没有问题,
但是,当我切换到 SQLServer 时,休眠不包括 shema 并且查询失败,
为休眠生成的查询如下所示:
select
areaauxili4_.idArea as idArea1_6_4_,
rutaArea(areaauxili4_.idArea) as formula2_4_
from
SIGAP.areasAuxiliar areaauxili4_
正在读取参数 hibernate.default_schema=SIGAP 并包含在 table 中,但不在函数中,
是否有 option/annotation 强制 shema 进入该功能?
我试过 hibernate 5.1 和 5.2,结果相同 :(
您可以使用 mysql-orm.xml
文件来覆盖您的公式,然后将您的构建配置为在数据库为 mysql.
时考虑该文件
在这里重写公式:
<entity-mappings
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm orm_2_1.xsd"
version="2.1">
<package>com.acme.persistence</package>
<entity class="AreaAuxiliar" access="FIELD">
<attributes>
<property name="ruta" formula="schemaName.RUTAAREA(idarea)"/>
</attributes>
</entity>
</entity-mappings>
然后在特定的persistence.xml
中添加引用。然后,您可以在您的构建中或在 运行 时间(参见下面的链接)用这个覆盖默认值 persistence.xml。
<persistence
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="persistenceUnit">
<provider>
org.hibernate.jpa.HibernatePersistenceProvider
</provider>
<mapping-file>
mappings/identifier/global/mysql-orm.xml
</mapping-file>
<class>
com.acme.persistence.AreaAuxiliar
</class>
</persistence-unit>
注:深受启发
1) 我知道对于 native 查询,您可以使用“{h-schema}”占位符(它将填充 "hibernate.default_schema" 的值参数):
"SELECT x FROM {h-schema}tableName"
试试看这是否也适用于@Formula...
2) 如果不是,您也可以尝试使用替换(即 hibernate.query.substitutions)来告诉休眠将文字 S 替换为 S' - 在您的情况下 "RUTAAREA" 为 "schema.RUTAAREA" ?
不确定这是否有助于应用于函数,但您是否尝试过将 属性 'schema' 添加到 @Table
注释中:
@Entity
@Table(name = "areasAuxiliar", schema="mySchemaName")
public final class AreaAuxiliar implements Serializable {
@Id
@Column(name = "idArea")
private Integer idArea;
@Formula("RUTAAREA(idArea)")
private String ruta;
另一种解决方案,转为注释,在@Formula
注解中使用占位符
@Entity
@Table(name = "areasAuxiliar")
public final class AreaAuxiliar implements Serializable {
@Id
@Column(name = "idArea")
private Integer idArea;
@Formula("{SCHEMA_AND_FUNCTION}")
private String ruta;
然后添加一个拦截器来填充公式的值。解决方案的 link 是
最后,请参阅我关于在 SQLSERVER 中创建全局函数的评论。可以在这里找到详细信息 Can I create create a global function in SQL Server?
更简单的解决方案:
改变你的@Formula:
@Formula("RUTAAREA(idArea)")
对此:
@Formula("{MYAPP_SCHEMA}.RUTAAREA(idArea)")
创建 class:
public class HibernateEntityInterceptor extends EmptyInterceptor {
}
在您的 sessionFactory 中将其注册为实体拦截器,在我的例子中:
sessionFactory.setEntityInterceptor(new HibernateEntityInterceptor());
然后在 class 中重写此方法:
public String onPrepareStatement(String sql) {
该方法在执行之前收到 sql 命令,因此,您需要做的就是简单地全部替换:
sql = sql.replaceAll("\{MYAPP_SCHEMA}", default_schema);
return sql;
感谢您的帮助。
我有一个带有 属性 @Formula 的实体,如下所示:
@Entity
@Table(name = "areasAuxiliar")
public final class AreaAuxiliar implements Serializable {
@Id
@Column(name = "idArea")
private Integer idArea;
@Formula("RUTAAREA(idArea)")
private String ruta;
当我将我的休眠配置为指向 Oracle 数据库时我没有问题, 但是,当我切换到 SQLServer 时,休眠不包括 shema 并且查询失败,
为休眠生成的查询如下所示:
select
areaauxili4_.idArea as idArea1_6_4_,
rutaArea(areaauxili4_.idArea) as formula2_4_
from
SIGAP.areasAuxiliar areaauxili4_
正在读取参数 hibernate.default_schema=SIGAP 并包含在 table 中,但不在函数中,
是否有 option/annotation 强制 shema 进入该功能?
我试过 hibernate 5.1 和 5.2,结果相同 :(
您可以使用 mysql-orm.xml
文件来覆盖您的公式,然后将您的构建配置为在数据库为 mysql.
在这里重写公式:
<entity-mappings
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm orm_2_1.xsd"
version="2.1">
<package>com.acme.persistence</package>
<entity class="AreaAuxiliar" access="FIELD">
<attributes>
<property name="ruta" formula="schemaName.RUTAAREA(idarea)"/>
</attributes>
</entity>
</entity-mappings>
然后在特定的persistence.xml
中添加引用。然后,您可以在您的构建中或在 运行 时间(参见下面的链接)用这个覆盖默认值 persistence.xml。
<persistence
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="persistenceUnit">
<provider>
org.hibernate.jpa.HibernatePersistenceProvider
</provider>
<mapping-file>
mappings/identifier/global/mysql-orm.xml
</mapping-file>
<class>
com.acme.persistence.AreaAuxiliar
</class>
</persistence-unit>
注:深受启发
1) 我知道对于 native 查询,您可以使用“{h-schema}”占位符(它将填充 "hibernate.default_schema" 的值参数):
"SELECT x FROM {h-schema}tableName"
试试看这是否也适用于@Formula...
2) 如果不是,您也可以尝试使用替换(即 hibernate.query.substitutions)来告诉休眠将文字 S 替换为 S' - 在您的情况下 "RUTAAREA" 为 "schema.RUTAAREA" ?
不确定这是否有助于应用于函数,但您是否尝试过将 属性 'schema' 添加到 @Table
注释中:
@Entity
@Table(name = "areasAuxiliar", schema="mySchemaName")
public final class AreaAuxiliar implements Serializable {
@Id
@Column(name = "idArea")
private Integer idArea;
@Formula("RUTAAREA(idArea)")
private String ruta;
另一种解决方案,转为注释,在@Formula
注解中使用占位符
@Entity
@Table(name = "areasAuxiliar")
public final class AreaAuxiliar implements Serializable {
@Id
@Column(name = "idArea")
private Integer idArea;
@Formula("{SCHEMA_AND_FUNCTION}")
private String ruta;
然后添加一个拦截器来填充公式的值。解决方案的 link 是
最后,请参阅我关于在 SQLSERVER 中创建全局函数的评论。可以在这里找到详细信息 Can I create create a global function in SQL Server?
更简单的解决方案:
改变你的@Formula:
@Formula("RUTAAREA(idArea)")
对此:
@Formula("{MYAPP_SCHEMA}.RUTAAREA(idArea)")
创建 class:
public class HibernateEntityInterceptor extends EmptyInterceptor {
}
在您的 sessionFactory 中将其注册为实体拦截器,在我的例子中:
sessionFactory.setEntityInterceptor(new HibernateEntityInterceptor());
然后在 class 中重写此方法:
public String onPrepareStatement(String sql) {
该方法在执行之前收到 sql 命令,因此,您需要做的就是简单地全部替换:
sql = sql.replaceAll("\{MYAPP_SCHEMA}", default_schema);
return sql;
感谢您的帮助。