"Missing table" 在物化视图上
"Missing table" on materialized view
我有以下实体:
@Entity
@Table(name = "full_address")
public class FullAddress {
@Id
@Column(name = "guid")
private String id;
@Column(name = "address")
private String address;
//getters and setters omitted
}
另外我创建物化视图如下:
CREATE TABLE address_table (
-- address fields,
aoid VARCHAR(36),
CONSTRAINT address_pk PRIMARY KEY (aoid)
);
CREATE MATERIALIZED VIEW full_address AS
SELECT buildFullAddressById(addrobj.aoid) AS address, addrobj.aoid AS guid FROM address_table AS addrobj;
-- buildFullAddressById is an sql function which is not important here
当我启动 Tomcat 应用程序时,我总是得到
org.hibernate.HibernateException: Missing table: full_address
为什么会这样?如何解决?
UPD:看起来像是休眠中的错误:https://hibernate.atlassian.net/browse/HHH-9602
这绝对是 Hibernate 的一个错误,在此处进行了描述:https://hibernate.atlassian.net/browse/HHH-9602
因此,我建议删除 hibernate.hbm2ddl.auto
属性 作为解决方法。
过去几天我遇到了同样的错误。正如 所说,可以在您的 persistence.xml
中禁用 hibernate.hbm2ddl.auto
属性,但如果您的项目正在快速开发,这不是一个好主意。
TL;DR: 将 属性 hibernate.hbm2dll.extra_physical_table_types
设置为 MATERIALIZED VIEW
.
或将 -Dhibernate.hbm2dll.extra_physical_table_types="MATERIALIZED VIEW"
添加到 VM 选项。但是最好配置文件这样的选项。
现在,我们正在使用 PostgreSQL 9.6 和 Hibernate 5.2。12.Final。不知何故,所有物化视图验证均失败,并出现以下异常:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException:
Schema-validation: missing table [our_project_schema.mv_one_of_views]
所有成功通过验证的实体都是简单的表或视图。
这似乎是通用数据库的默认行为。在第 79-81
行的来源 here 中,他们只添加了这些类型:
final List<String> tableTypesList = new ArrayList<>();
tableTypesList.add( "TABLE" );
tableTypesList.add( "VIEW" );
行 85-87
告诉我们可以用自定义值扩展这些硬编码值:
if ( extraPhysicalTableTypes != null ) {
Collections.addAll( tableTypesList, extraPhysicalTableTypes );
}
在行 56
上声明 private String[] extraPhysicalTableTypes;
,
在第 71-77
行,此数组中添加了更多值:
if ( !"".equals( extraPhysycalTableTypesConfig.trim() ) ) {
this.extraPhysicalTableTypes = StringHelper.splitTrimmingTokens(
",;",
extraPhysycalTableTypesConfig,
false
);
}
它们来自行 66-70
,在键 EXTRA_PHYSICAL_TABLE_TYPES
下编码为字符串,默认值为空:
final String extraPhysycalTableTypesConfig = configService.getSetting(
AvailableSettings.EXTRA_PHYSICAL_TABLE_TYPES,
StandardConverters.STRING,
""
);
行 1545
上的 here 是该密钥的声明:
/**
* Identifies a comma-separate list of values to specify extra table types,
* other than the default "TABLE" value, to recognize as defining a physical table
* by schema update, creation and validation.
*
* @since 5.0
*/
String EXTRA_PHYSICAL_TABLE_TYPES = "hibernate.hbm2dll.extra_physical_table_types";
因此,添加此 属性 将向 tableTypesList
添加另一个条目,用于过滤数据库中的许多其他实体,例如序列、索引、临时表和其他可能具有名称与您的物化视图相似。
这是我的 persistence.xml
的样子,如果您有兴趣:
<?xml version="1.0" encoding="UTF-8"?>
<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="project-pu">
<jta-data-source>java:jboss/datasources/project-pu</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.hbm2dll.extra_physical_table_types" value="MATERIALIZED VIEW"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.use_sql_comments" value="false"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/mgt"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
</properties>
</persistence-unit>
</persistence>
P.S。我知道这是一个很老的post,但我为这个问题奋斗了几天。我没有找到答案,所以我决定把它放在互联网上的某个地方。而这个地方变成了这里。 :)
我发现最简单的解决方案(假设您仍想使用 Hibernate 来验证架构)是向 table 定义添加一个子选择。
使用hbm.xml
<hibernate-mapping>
<class name="com.initech.MvObject" table="MV_OBJ">
<!-- This is necessary when using older Hibernate versions because of
Hibernate bugs. See
https://hibernate.atlassian.net/browse/HHH-1329
https://hibernate.atlassian.net/browse/HHH-9602
-->
<subselect>select * from MV_OBJ</subselect>
使用注释
import org.hibernate.annotations.Subselect;
import javax.persistence.Entity;
@Entity
@Subselect("select * from MV_OBJ")
public class MvObj{
}
我有以下实体:
@Entity
@Table(name = "full_address")
public class FullAddress {
@Id
@Column(name = "guid")
private String id;
@Column(name = "address")
private String address;
//getters and setters omitted
}
另外我创建物化视图如下:
CREATE TABLE address_table (
-- address fields,
aoid VARCHAR(36),
CONSTRAINT address_pk PRIMARY KEY (aoid)
);
CREATE MATERIALIZED VIEW full_address AS
SELECT buildFullAddressById(addrobj.aoid) AS address, addrobj.aoid AS guid FROM address_table AS addrobj;
-- buildFullAddressById is an sql function which is not important here
当我启动 Tomcat 应用程序时,我总是得到
org.hibernate.HibernateException: Missing table: full_address
为什么会这样?如何解决?
UPD:看起来像是休眠中的错误:https://hibernate.atlassian.net/browse/HHH-9602
这绝对是 Hibernate 的一个错误,在此处进行了描述:https://hibernate.atlassian.net/browse/HHH-9602
因此,我建议删除 hibernate.hbm2ddl.auto
属性 作为解决方法。
过去几天我遇到了同样的错误。正如 persistence.xml
中禁用 hibernate.hbm2ddl.auto
属性,但如果您的项目正在快速开发,这不是一个好主意。
TL;DR: 将 属性 hibernate.hbm2dll.extra_physical_table_types
设置为 MATERIALIZED VIEW
.
或将 -Dhibernate.hbm2dll.extra_physical_table_types="MATERIALIZED VIEW"
添加到 VM 选项。但是最好配置文件这样的选项。
现在,我们正在使用 PostgreSQL 9.6 和 Hibernate 5.2。12.Final。不知何故,所有物化视图验证均失败,并出现以下异常:
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [our_project_schema.mv_one_of_views]
所有成功通过验证的实体都是简单的表或视图。
这似乎是通用数据库的默认行为。在第 79-81
行的来源 here 中,他们只添加了这些类型:
final List<String> tableTypesList = new ArrayList<>();
tableTypesList.add( "TABLE" );
tableTypesList.add( "VIEW" );
行 85-87
告诉我们可以用自定义值扩展这些硬编码值:
if ( extraPhysicalTableTypes != null ) {
Collections.addAll( tableTypesList, extraPhysicalTableTypes );
}
在行 56
上声明 private String[] extraPhysicalTableTypes;
,
在第 71-77
行,此数组中添加了更多值:
if ( !"".equals( extraPhysycalTableTypesConfig.trim() ) ) {
this.extraPhysicalTableTypes = StringHelper.splitTrimmingTokens(
",;",
extraPhysycalTableTypesConfig,
false
);
}
它们来自行 66-70
,在键 EXTRA_PHYSICAL_TABLE_TYPES
下编码为字符串,默认值为空:
final String extraPhysycalTableTypesConfig = configService.getSetting(
AvailableSettings.EXTRA_PHYSICAL_TABLE_TYPES,
StandardConverters.STRING,
""
);
行 1545
上的 here 是该密钥的声明:
/**
* Identifies a comma-separate list of values to specify extra table types,
* other than the default "TABLE" value, to recognize as defining a physical table
* by schema update, creation and validation.
*
* @since 5.0
*/
String EXTRA_PHYSICAL_TABLE_TYPES = "hibernate.hbm2dll.extra_physical_table_types";
因此,添加此 属性 将向 tableTypesList
添加另一个条目,用于过滤数据库中的许多其他实体,例如序列、索引、临时表和其他可能具有名称与您的物化视图相似。
这是我的 persistence.xml
的样子,如果您有兴趣:
<?xml version="1.0" encoding="UTF-8"?>
<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="project-pu">
<jta-data-source>java:jboss/datasources/project-pu</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.spatial.dialect.postgis.PostgisPG95Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.hbm2dll.extra_physical_table_types" value="MATERIALIZED VIEW"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="hibernate.use_sql_comments" value="false"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/mgt"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
</properties>
</persistence-unit>
</persistence>
P.S。我知道这是一个很老的post,但我为这个问题奋斗了几天。我没有找到答案,所以我决定把它放在互联网上的某个地方。而这个地方变成了这里。 :)
我发现最简单的解决方案(假设您仍想使用 Hibernate 来验证架构)是向 table 定义添加一个子选择。
使用hbm.xml
<hibernate-mapping>
<class name="com.initech.MvObject" table="MV_OBJ">
<!-- This is necessary when using older Hibernate versions because of
Hibernate bugs. See
https://hibernate.atlassian.net/browse/HHH-1329
https://hibernate.atlassian.net/browse/HHH-9602
-->
<subselect>select * from MV_OBJ</subselect>
使用注释
import org.hibernate.annotations.Subselect;
import javax.persistence.Entity;
@Entity
@Subselect("select * from MV_OBJ")
public class MvObj{
}