Java 在 Oracle 数据库中写入时,Springboot 应用程序没有增加 ID,而是出现错误
Java Springboot application is not increasing ID when writing in Oracle database instead I get an error
我有一个 java springboot 应用程序,我在其中创建了一个 table with liquibase 我想在其中编写对象历史记录。但是对象的id并没有增加,而是我得到一个错误,当id为null时,数据库无法将对象写入数据库。
我想在数据库中写入的对象如下所示:
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>
有人对此有想法吗?
谢谢:)
您好,我找到了解决方案。
看来Oracle需要一个序列来增加一个对象的id。
我的历史对象现在看起来像这样:
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 数据库测试了我的更新日志,但没有发现这个错误。
无论如何,我希望这对任何人都有帮助:)
要自动生成 id
您需要更改 @GeneratedValue
并在 History
class.
中添加 @SequenceGenerator
注释
在 ChangeLog
之前创建新的 table 创建序列。
- 添加所需的注释
@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"
。因为主键已经不可为空且唯一。
我有一个 java springboot 应用程序,我在其中创建了一个 table with liquibase 我想在其中编写对象历史记录。但是对象的id并没有增加,而是我得到一个错误,当id为null时,数据库无法将对象写入数据库。
我想在数据库中写入的对象如下所示:
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>
有人对此有想法吗? 谢谢:)
您好,我找到了解决方案。 看来Oracle需要一个序列来增加一个对象的id。 我的历史对象现在看起来像这样:
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 数据库测试了我的更新日志,但没有发现这个错误。
无论如何,我希望这对任何人都有帮助:)
要自动生成 id
您需要更改 @GeneratedValue
并在 History
class.
中添加 @SequenceGenerator
注释
在 ChangeLog
之前创建新的 table 创建序列。
- 添加所需的注释
@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"
。因为主键已经不可为空且唯一。