PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Table manquante sur la vue matérialisée

J'ai le même bug depuis plusieurs jours. Comme cette réponse dit, il est possible de désactiver hibernate.hbm2ddl.auto propriété dans votre persistence.xml , mais ce n'est pas une bonne idée si votre projet se développe rapidement.

TL;DR : définir la propriété hibernate.hbm2dll.extra_physical_table_types vers MATERIALIZED VIEW .

Ou ajoutez -Dhibernate.hbm2dll.extra_physical_table_types="MATERIALIZED VIEW" aux options de machine virtuelle. Mais il vaut mieux mettre de telles options dans le fichier de configuration.

Pour le moment, nous utilisons PostgreSQL 9.6 et Hibernate 5.2.12.Final. D'une manière ou d'une autre, toutes les validations des vues matérialisées échouaient à l'exception suivante :

Toutes les entités qui ont réussi la validation étaient soit de simples tables, soit des vues.

Il semble que ce soit un comportement par défaut pour les bases de données génériques. Dans les sources ici sur les lignes 79-81 ils n'ajoutent que ces types :

final List<String> tableTypesList = new ArrayList<>();
tableTypesList.add( "TABLE" );
tableTypesList.add( "VIEW" );

Lignes 85-87 dites-nous qu'il est possible d'étendre ces valeurs codées en dur avec des valeurs personnalisées :

if ( extraPhysicalTableTypes != null ) {
    Collections.addAll( tableTypesList, extraPhysicalTableTypes );
}

En ligne 56 il est déclaré private String[] extraPhysicalTableTypes; , et aux lignes 71-77 il y a quelques valeurs supplémentaires ajoutées dans ce tableau :

if ( !"".equals( extraPhysycalTableTypesConfig.trim() ) ) {
    this.extraPhysicalTableTypes = StringHelper.splitTrimmingTokens(
        ",;",
        extraPhysycalTableTypesConfig,
        false
    );
}

Ils proviennent des lignes 66-70 , encodé sous forme de chaîne sous la clé EXTRA_PHYSICAL_TABLE_TYPES avec une valeur par défaut vide :

final String extraPhysycalTableTypesConfig = configService.getSetting(
    AvailableSettings.EXTRA_PHYSICAL_TABLE_TYPES,
    StandardConverters.STRING,
    ""
);

Et ici en ligne 1545 est la déclaration de cette clé :

/**
 * 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";

Ainsi, l'ajout de cette propriété ajoutera une autre entrée à tableTypesList qui est utilisé pour filtrer de nombreuses autres entités dans la base de données, telles que des séquences, des index, des tables temporaires et autres, qui peuvent avoir un nom similaire à la vôtre vue matérialisée.

Voici comment mon persistence.xml ressemble, si vous êtes intéressé :

<?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>

PS Je sais que c'est un très vieux post, mais je me suis battu avec ce problème pendant quelques jours. Je n'ai pas trouvé de réponse, alors j'ai décidé de la mettre quelque part sur Internet. Et ce quelque part est devenu ici. :)