Java Springboot应用在向Oracle数据库写入时未递增ID,而是出现错误。

huangapple go评论77阅读模式
英文:

Java Springboot application is not increasing ID when writing in Oracle database instead I get an error

问题

我有一个Java Spring Boot应用程序,在其中我使用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>

有人对此有什么想法吗?谢谢 Java Springboot应用在向Oracle数据库写入时未递增ID,而是出现错误。

英文:

I have a java springboot application in which I am creating a table with liquibase in which I want to write an object history. However the id of the object is not increasing, instead I get an error that the database cannot write an object to the database when the id is null.

My object I want to write in the database looks like this:

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 = &quot;history&quot;)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class History{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = &quot;ID&quot;, nullable = false, updatable = false)
    private long id;
    @Column(name = &quot;name&quot;, nullable = true)
    private String name;
    ...
}

My liquibase changelog looks like this:

&lt;databaseChangeLog
        xmlns:xsi=&#39;http://www.w3.org/2001/XMLSchema-instance&#39;
        xmlns=&#39;http://www.liquibase.org/xml/ns/dbchangelog&#39;
        xsi:schemaLocation=&#39;http://www.liquibase.org/xml/ns/dbchangelog
                            http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd'>

    &lt;changeSet id=&#39;01-create table history&#39; author=&#39;M. K.&#39;&gt;
        &lt;createTable tableName=&#39;history&#39;
                     remarks=&#39;A table to contain all history.&#39;&gt;
            &lt;column autoIncrement=&#39;true&#39; name=&#39;ID&#39;
                    type=&#39;INTEGER&#39;&gt;
                &lt;constraints nullable=&#39;false&#39; primaryKey=&#39;true&#39; primaryKeyName=&#39;HISTORYKEY&#39;/&gt;
            &lt;/column&gt;
            &lt;column name=&#39;NAME&#39; type=&#39;varchar(100)&#39;&gt;
                &lt;constraints nullable=&#39;true&#39;/&gt;
            &lt;/column&gt;
...

        &lt;/createTable&gt;
    &lt;/changeSet&gt;
&lt;/databaseChangeLog&gt;

Has anybody ideas on this?
Thank you Java Springboot应用在向Oracle数据库写入时未递增ID,而是出现错误。

答案1

得分: 0

我找到了解决方案
似乎 Oracle 需要一个序列来增加对象的 ID
我的 history 对象现在看起来像这样

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 数据库上测试了我的变更日志但没有发现此错误

无论如何希望这能帮助任何人 :)
英文:

Hi I found the solution.
It seems that Oracle needs a sequence to increase the id of an object.
My history object looks now like this:

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 = &quot;history&quot;)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class History {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = &quot;HISTORYSEQ&quot;)
@SequenceGenerator(name = &quot;HISTORYSEQ&quot;, sequenceName = &quot;HISTORYSEQ&quot;, allocationSize = 1)
@Column(name = &quot;ID&quot;, nullable = false, updatable = false)
private long id;
@Column(name = &quot;name&quot;, nullable = true)
private String name;
...
}

And my liquibase changelog looks like this:

&lt;databaseChangeLog
xmlns:xsi=&#39;http://www.w3.org/2001/XMLSchema-instance&#39;
xmlns=&#39;http://www.liquibase.org/xml/ns/dbchangelog&#39;
xsi:schemaLocation=&#39;http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd'>
&lt;changeSet id=&#39;01-create table history&#39; author=&#39;M. K.&#39;&gt;
&lt;createSequence  startValue=&quot;1&quot; incrementBy=&quot;1&quot; ordered=&quot;true&quot; sequenceName=&quot;HISTORYSEQ&quot; maxValue=&quot;9223372036854775807&quot; minValue=&quot;1&quot; cacheSize=&quot;2&quot;/&gt;       
&lt;createTable tableName=&#39;history&#39;
remarks=&#39;A table to contain all history.&#39;&gt;
&lt;column name=&#39;ID&#39; type=&#39;INTEGER&#39;&gt;
&lt;constraints nullable=&#39;false&#39; primaryKey=&#39;true&#39;/&gt;
&lt;/column&gt;
&lt;column name=&#39;NAME&#39; type=&#39;varchar(100)&#39;&gt;
&lt;constraints nullable=&#39;true&#39;/&gt;
&lt;/column&gt;
...
&lt;/createTable&gt;
&lt;/changeSet&gt;
&lt;/databaseChangeLog&gt;

Attention: The cache size has to be 2 or bigger.

I tested my changelog with h2 database, but this error was not found.

Anyway, I hope this helps anybody Java Springboot应用在向Oracle数据库写入时未递增ID,而是出现错误。

答案2

得分: 0

自动生成id需要在History类中更改@GeneratedValue并添加@SequenceGenerator注解。
在创建新表之前,在ChangeLog中创建序列。


  1. 添加所需的注解
@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;
  1. 在变更日志中添加标签以创建序列。可选地,您可以删除一些不必要的标签参数:
<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"。因为主键已经是非空且唯一的。
英文:

To auto generate id you need to change @GeneratedValue and add @SequenceGenerator annotations in History class.
In ChangeLog before creating new table create sequence.


  1. Add required annotations
@Id
@SequenceGenerator(name = &quot;seq_history&quot;, sequenceName = &quot;seq_history_id&quot;, allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = &quot;seq_history&quot;)
@Column(unique = true, updatable = false, nullable = false)
private long id;
  1. Add tag in change log to create sequence. Optional you can remove some unnecessary tag parameters:
&lt;changeSet id=&#39;1&#39; author=&#39;M. K.&#39;&gt;

    &lt;createSequence incrementBy=&quot;1&quot; sequenceName=&quot;seq_history_id&quot; startValue=&quot;1&quot;/&gt;

    &lt;createTable tableName=&#39;history&#39;&gt;
        &lt;column name=&#39;id&#39; type=&#39;bigint&#39;&gt;
            &lt;constraints primaryKey=&#39;true&#39; primaryKeyName=&#39;pk_history&#39;/&gt;
        &lt;/column&gt;
...

    &lt;/createTable&gt;
&lt;/changeSet&gt;

This is the way how I work with auto increment. I can ensure it works.


Additional info about liquibase change logs:

  • If you use oracle you don't need to write names in upper case, because it might not work if you going to change database type (not oracle). Oracle automatically converts i.e. column names to upper case.
  • You can remove nullable=&quot;false&quot; if column is primary key. Because primary key is already not nullable and unique.

huangapple
  • 本文由 发表于 2020年10月22日 13:33:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/64475873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定