【问题标题】:GenerationType.AUTO vs GenerationType.IDENTITY in hibernate休眠中的 GenerationType.AUTO 与 GenerationType.IDENTITY
【发布时间】:2016-01-10 20:06:24
【问题描述】:

目前,我们使用 MySQL 作为数据库,我们使用

@Generated Value(strategy = GenerationType.IDENTITY)

在我们需要将数据库迁移到 Oracle 的某些情况下它运行良好,但此时它无法正常运行。如果有人知道这背后的实际区别是什么以及它是如何工作的?

【问题讨论】:

  • 您使用的是什么 ORM 提供程序?
  • 如果你使用GenerationType.AUTO,那么默认情况下hibernate使用hibernate_sequence作为所有表使用的序列,并且一次只能使用一个序列值,这意味着如果使用序列1,那么它不能在其他任何地方使用。但是对于GenerationType.IDENTITY,ID 仅对于该特定列是唯一的。 (测试数据库 - MySQL)

标签: java hibernate spring-mvc jpa


【解决方案1】:

我使用 JPA 和 Oracle 11g,对我有用的解决方案如下

package com.example.springsocial.model;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "rol", uniqueConstraints = {
        @UniqueConstraint(columnNames = "name")
})
public class Rol {
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="rol_sequence")
    @SequenceGenerator(name="rol_sequence", sequenceName="rol_sequence", allocationSize=100)
    private Long id;

    @Column(nullable = false)
    private String name;

    private Date createdAt;
    @Column(nullable = true)
    private Date updatedAt;
    @Column(nullable = true)
    private Integer createdBy;
    @Column(nullable = true)
    private Integer updatedBy;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public Integer getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(Integer createdBy) {
        this.createdBy = createdBy;
    }

    public Integer getUpdatedBy() {
        return updatedBy;
    }

    public void setUpdatedBy(Integer updatedBy) {
        this.updatedBy = updatedBy;
    }
}

【讨论】:

    【解决方案2】:

    引用Java Persistence/Identity and Sequencing:

    Identity 排序使用数据库中的特殊 IDENTITY 列,以允许数据库在插入行时自动为对象分配 id。许多数据库都支持标识列,例如 MySQL、DB2、SQL Server、Sybase 和 Postgres。 Oracle 不支持 IDENTITY 列,但可以通过使用序列对象和触发器来模拟它们。

    所以我更喜欢使用 SEQUENCE 代替

    序列对象使用特殊的数据库对象来生成 ID。仅在某些数据库中支持序列对象,例如 Oracle、DB2 和 Postgres。通常,SEQUENCE 对象具有名称、INCREMENT 和其他数据库对象设置。每次选择 .NEXTVAL 时,序列都会增加 INCREMENT。

    例子:

    @Entity
    public class Employee {
        @Id
        @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EMP_SEQ")
        @SequenceGenerator(name="EMP_SEQ", sequenceName="EMP_SEQ", allocationSize=100)
        private long id;
        ...
    }
    

    【讨论】:

      【解决方案3】:

      它如何与 Oracle 一起“正常工作”(您没有像您的意思那样定义基本信息)?我看不到 AUTO 与您的问题的相关性 - 这只是让实现选择它想要使用的内容。

      IDENTITY”(根据 JPA javadocs 和规范 - 您应该指的是)表示 自动增量。在 Oracle 中没有这样的概念,但在 MySQL、SQLServer 和其他一些中却有。我希望任何体面的 JPA 实现都能在尝试这样的事情时标记错误。

      Oracle 将允许使用“SEQUENCE”或“TABLE”策略

      【讨论】:

      • 是的,正如你所说,oracle 中没有自动增量选项。但是如果我使用 GenerationType.AUTO,则模型适用于 oracle 数据库,因为如果我给 Auto,JPA 会自动根据数据库。感谢您的澄清。
      猜你喜欢
      • 1970-01-01
      • 2016-04-21
      • 2015-09-13
      • 2011-03-05
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多