java - 为什么 Hibernate 使用序列

标签 java mysql hibernate

我的父实体和子实体的 ID 是使用策略 GenerationType.TABLE 生成的因为我正在使用 MySQL 数据库。

如果我在不指定 ID 的情况下创建父级(即,第一次创建父级),向其中添加新的子级,并保存父级,则 hibernate 将按预期工作并使用 MySQL AUTO_INCREMENT 列功能。

但是,如果我创建一个父级并指定一个 ID(即实例化已持久化的父级),向其中添加一个子级并保存该子级,则 hibernate 会发出 select sequence_next_hi_value from hibernate_sequences ...并将其用作 child 的 PK。

同样,如果我通过 session.get(Parent, 1) 从数据库获取父级来实例化它,向其中添加一个新的子进程,并保存父进程或子进程,然后 hibernate 使用序列来获取子进程的 PK。

如果我创建足够多的新父项(确切地说是 32767 个)来运行 mysql AUTO_INCRMENT 计数器,则会由于主键不够唯一而导致失败。

这是我的父实体和子实体(分别命名为“位置”和“类别”):

@Entity(name="location")
public class Location {
    @Id @GeneratedValue(strategy=GenerationType.TABLE) @Column(name="location_id")
    private int id;

    @OneToMany(mappedBy="location")
    @Cascade(CascadeType.SAVE_UPDATE)
    private List<Category> categories;

    ...
}

@Entity(name="category")
public class Category {
    @ID @GeneratedValue(strategy=GenerationType.TABLE) @Column(name="category_id")
    private int id;

    @ManyToOne @JoinColumn(name="location_id")
    private Location location;
}

这是 hibernate 代码:

Hibernate: select sequence_next_hi_value from hibernate_sequences where sequence_name = 'category' for update
Hibernate: update hibernate_sequences set sequence_next_hi_value = ? where sequence_next_hi_value = ? and sequence_name = 'category'
Hibernate: insert into category (location_id, category_id) values (?, ?)

最佳答案

事先:我不知道为什么 hibernate 在保存你的子记录时使用另一种策略。但我可能会给你一些关于你描述的其他问题的答案或提示:

关于策略GenerationType.TABLE,您的应用程序依赖于生成ID的数据库功能。这可能会导致插入的每个新数据库记录都需要数据库往返。当使用像 hi-lo 这样的替代策略时,生成器将通过仅联系数据库一次来保留一堆 id(例如 100 或 1000)。这可能会大大提高性能。另一方面,当应用程序重新启动时,您可能会丢失一些ID。如果您可能面临这个问题,则应该考虑一下。

使用不依赖数据库产品的策略的另一个好处是,如果您切换数据库,您可以保留映射。

关于java - 为什么 Hibernate 使用序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22779313/

相关文章:

java - Android drawTextOnPath() 不显示输出

mysql - 使用 Docker 命令从 Mysql 导出 View

JAVA hibernate/webservice - 时间戳问题

java - Spring Boot 不记录 CQL 查询

JavaFX TableView 可编辑(true)不起作用

java - 在 Java 中查找字符串中的单词

java - 从 Java 调用 Maven 目标

php - 如何在Codeigniter中将 session 数据存储到数据库中?

php - 根据第一个选择选项更改表单选择选项?

java - 涉及继承时如何在Hibernate/JPA中指定列名?