【问题标题】:"Missing table" on materialized view物化视图上的“缺失表”
【发布时间】:2015-09-17 07:56:38
【问题描述】:

我有以下实体:

@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 应用程序时,我总是得到 ​​p>

org.hibernate.HibernateException:缺少表:full_address

为什么会这样?如何解决?

UPD:看起来像休眠中的错误:https://hibernate.atlassian.net/browse/HHH-9602

【问题讨论】:

  • 您是否检查了您的授予权限?

标签: java hibernate postgresql jpa materialized-views


【解决方案1】:

过去几天我遇到了同样的错误。正如this answer 所说,可以在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。不知何故,所有物化视图验证都失败了,但出现以下异常:

引起:org.hibernate.tool.schema.spi.SchemaManagementException: 架构验证:缺少表 [our_project_schema.mv_one_of_views]

所有成功通过验证的实体都是简单的表或视图。

这似乎是通用数据库的默认行为。在here79-81 上的源代码中,他们只添加了这些类型:

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>

附:我知道这是一个非常古老的帖子,但我与这个问题斗争了几天。我没有找到答案,所以我决定把它放在互联网的某个地方。而这个地方变成了这里。 :)

【讨论】:

  • 感谢您抽出宝贵时间记录此内容。非常感激。 :)
【解决方案2】:

这绝对是 Hibernate 的一个错误,这里有描述:https://hibernate.atlassian.net/browse/HHH-9602

因此,我建议将hibernate.hbm2ddl.auto 属性作为一种解决方法。

【讨论】:

    【解决方案3】:

    我发现最简单的解决方案(假设您仍想使用 Hibernate 来验证架构)是在表定义中添加一个子选择。

    使用 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{
    
    }
    

    【讨论】:

    • 你救我!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2018-04-26
    相关资源
    最近更新 更多