#java #oracle #spring-boot #h2 #liquibase
#java #Oracle #spring-boot #h2 #liquibase
Вопрос:
У меня есть приложение java springboot, в котором я создаю таблицу с liquibase, в которую я хочу записать историю объектов. Однако идентификатор объекта не увеличивается, вместо этого я получаю сообщение об ошибке, что база данных не может записать объект в базу данных, когда идентификатор равен нулю.
Мой объект, который я хочу записать в базу данных, выглядит следующим образом:
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "history")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class History{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "ID", nullable = false, updatable = false)
private long id;
@Column(name = "name", nullable = true)
private String name;
...
}
Мой список изменений liquibase выглядит следующим образом:
<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.5.xsd'>
<changeSet id='01-create table history' author='M. K.'>
<createTable tableName='history'
remarks='A table to contain all history.'>
<column autoIncrement='true' name='ID'
type='INTEGER'>
<constraints nullable='false' primaryKey='true' primaryKeyName='HISTORYKEY'/>
</column>
<column name='NAME' type='varchar(100)'>
<constraints nullable='true'/>
</column>
...
</createTable>
</changeSet>
</databaseChangeLog>
У кого-нибудь есть идеи по этому поводу?
Спасибо 🙂
Ответ №1:
Для автоматической генерации id
вам необходимо изменить @GeneratedValue
и добавить @SequenceGenerator
аннотации в History
классе. ChangeLog
Перед созданием новой таблицы создайте последовательность.
- Добавьте необходимые аннотации
@Id
@SequenceGenerator(name = "seq_history", sequenceName = "seq_history_id", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_history")
@Column(unique = true, updatable = false, nullable = false)
private long id;
- Добавьте тег в журнал изменений, чтобы создать последовательность. Необязательно, вы можете удалить некоторые ненужные параметры тега:
<changeSet id='1' author='M. K.'>
<createSequence incrementBy="1" sequenceName="seq_history_id" startValue="1"/>
<createTable tableName='history'>
<column name='id' type='bigint'>
<constraints primaryKey='true' primaryKeyName='pk_history'/>
</column>
...
</createTable>
</changeSet>
Именно так я работаю с автоматическим увеличением. Я могу гарантировать, что это работает.
Дополнительная информация о журналах изменений liquibase:
- Если вы используете oracle, вам не нужно писать имена в верхнем регистре, потому что это может не сработать, если вы собираетесь изменить тип базы данных (не oracle). Oracle автоматически преобразует, например, имена столбцов в верхний регистр.
- Вы можете удалить
nullable="false"
, если столбец является первичным ключом. Поскольку первичный ключ уже не является обнуляемым и уникальным.
Ответ №2:
Привет, я нашел решение. Кажется, что Oracle нужна последовательность для увеличения идентификатора объекта. Теперь мой объект истории выглядит так:
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "history")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class History {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HISTORYSEQ")
@SequenceGenerator(name = "HISTORYSEQ", sequenceName = "HISTORYSEQ", allocationSize = 1)
@Column(name = "ID", nullable = false, updatable = false)
private long id;
@Column(name = "name", nullable = true)
private String name;
...
}
И мой список изменений liquibase выглядит следующим образом:
<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.5.xsd'>
<changeSet id='01-create table history' author='M. K.'>
<createSequence startValue="1" incrementBy="1" ordered="true" sequenceName="HISTORYSEQ" maxValue="9223372036854775807" minValue="1" cacheSize="2"/>
<createTable tableName='history'
remarks='A table to contain all history.'>
<column name='ID' type='INTEGER'>
<constraints nullable='false' primaryKey='true'/>
</column>
<column name='NAME' type='varchar(100)'>
<constraints nullable='true'/>
</column>
...
</createTable>
</changeSet>
</databaseChangeLog>
Внимание: размер кэша должен быть 2 или больше.
Я протестировал свой журнал изменений с базой данных h2, но эта ошибка не была найдена.
В любом случае, я надеюсь, что это кому-нибудь поможет 🙂