Hibernate Envers + Liquibase: NULL недопустим для столбца «REV» - PullRequest
0 голосов
/ 28 мая 2020

Я хочу добавить Liquibase в приложение, которое уже использует Hibernate Envers, но с автоматическим созданием таблиц базы данных. Следовательно, мне нужно написать наборы изменений Liquibase, которые содержат таблицы для моих сущностей и таблицу, необходимую для Envers.

Вот набор изменений:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
     http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

<property name="long_type" value="bigint" dbms="postgresql"/>
<property name="long_type" value="long" dbms="h2"/>

<changeSet id="CreateBasicSchema" author="Steven Schwenke">

    <createSequence sequenceName="hibernate_sequence" startValue="0" incrementBy="1"/>

    <createTable tableName="revinfo">
        <column name="rev" type="integer">
            <constraints primaryKey="true"/>
        </column>
        <column name="revtstmp" type="bigint"/>
    </createTable>

    <createTable tableName="stuff">
        <column name="id" type="${long_type}">
            <constraints nullable="false" unique="true" primaryKey="true"/>
        </column>
        <column name="text" type="varchar(36)">
            <constraints nullable="false"/>
        </column>
    </createTable>

    <createTable tableName="stuff_aud">
        <column name="id" type="${long_type}">
            <constraints nullable="false" unique="true" primaryKey="true"/>
        </column>
        <column name="rev" type="integer">
            <constraints referencedTableName="revinfo"
                         foreignKeyName="fk_brands_stuff_revinfo"
                         referencedColumnNames="rev"
                         nullable="false"/>
        </column>
        <column name="revtype" type="integer">
            <constraints nullable="false"/>
        </column>
        <column name="stuff" type="varchar(36)">
            <constraints nullable="true"/>
        </column>
    </createTable>
</changeSet>

Это вызывает следующее исключение:

o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 23502, SQLState: 23502
o.h.engine.jdbc.spi.SqlExceptionHelper   : NULL nicht zulässig für Feld "REV"
NULL not allowed for column "REV"; SQL statement:
/* insert org.hibernate.envers.DefaultRevisionEntity */ insert into revinfo (rev, revtstmp) values (null, ?) [23502-200]
org.springframework.dao.DataIntegrityViolationException: could not execute statement ...

После некоторого исследования я наконец нашел свою ошибку и опубликую ее как ответ на этот вопрос. Надеюсь, что это поможет другим разработчикам столкнуться с тем же исключением.

1 Ответ

0 голосов
/ 28 мая 2020

Отсутствующая часть - это простой autoIncrement для идентификатора таблицы revinfo:

<createTable tableName="revinfo">
    <column name="rev" type="integer" autoIncrement="true">
        <constraints primaryKey="true"/>
    </column>
    <column name="revtstmp" type="bigint"/>
</createTable>

Без этого новые записи в таблице revinfo будут иметь нулевой идентификатор, который именно то, что говорит исключение.

Другая ошибка в приведенном выше коде Liquibase заключается в том, что идентификатор aud-table имеет первичный ключ только на идентификаторе. Это приведет к исключениям при обновлении сущностей. По словам Влада Михалчи, для таблицы aud должен быть комбинированный ключ:

<createTable tableName="stuff_aud">
    <column name="id" type="${long_type}">
        <constraints nullable="false" />
    </column>
    <column name="rev" type="integer">
        <constraints referencedTableName="revinfo"
                     foreignKeyName="fk_brands_stuff_revinfo"
                     referencedColumnNames="rev"
                     nullable="false"/>
    </column>
    <column name="revtype" type="integer">
        <constraints nullable="false"/>
    </column>
    <column name="stuff" type="varchar(36)">
        <constraints nullable="false"/>
    </column>
</createTable>
<addPrimaryKey tableName="stuff_aud" columnNames="id, rev" />
...