抽象超类和 MySQL 的 @GeneeratedValue 陷阱
尝试使用 Hibernate 和 MySQL 管理 Spring 应用程序中的 ID 值,使用抽象超类 BaseEntity 可能会带来挑战。当使用 @GenerateValue(strategy = GenerationType.TABLE) 时,由于缺少 Hibernate 增量生成 ID 所需的 hibernate_sequences 表而出现错误。
潜在问题
MySQL 本身并不支持序列,这给 GenerationType.TABLE 方法带来了障碍。该策略通常利用专用表来跟踪序列值并分配唯一 ID。由于 MySQL 缺少此功能,因此会导致“表 'docbd.hibernate_sequences' 不存在”错误。
解决问题
要克服此问题,成功持久化对象,需要一个解决方法:
1。使用 GenerationType.IDENTITY
这种策略依赖于数据库自身的自增机制,这样就不需要专门的序列表了。但是,它与使用抽象超类来管理跨派生类的 ID 的意图不兼容。
2.创建 Hibernate 序列表
尽管 MySQL 缺乏本机序列支持,但它允许创建自定义表来模拟序列行为。下面是创建名为 hibernate_sequences 的表的示例:
CREATE TABLE IF NOT EXISTS hibernate_sequences( sequence_name VARCHAR(255) NOT NULL, sequence_next_hi_value INT UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (sequence_name) ) ENGINE=InnoDB;
3。配置 Hibernate 以使用自定义序列
在 BaseEntity 类中,调整 @GenerateValue 注解以使用自定义序列表:
@GeneratedValue(strategy = GenerationType.TABLE, generator = "hilo_generator") private Integer id; @SequenceGenerator(name = "hilo_generator", sequenceName = "hibernate_sequences", allocationSize = 1)
4.调整实体表中的列定义
CCD表中,确保id列定义对应自定义序列:
CREATE TABLE IF NOT EXISTS ccd( id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, #other stuff ) ENGINE=InnoDB;
后备方法
作为最后的手段,如果自定义序列方法由于其他意外问题而失败,请考虑在 BaseEntity 类中实现手动 ID 生成机制:
private static int idSequence = 0; public Integer getId() { if (id == null) { return idSequence++; } return id; }
结论
在带有 Hibernate 和 MySQL 的 Spring 应用程序中使用抽象超类进行 ID 管理需要仔细考虑底层数据库的限制。采用创建自定义序列表的解决方法可以缓解由于 MySQL 缺乏本机序列支持而导致的问题。然而,这些方法可能会产生性能影响或给系统设计带来额外的复杂性。
以上是为什么将 @GenerateValue(strategy = GenerationType.TABLE) 与抽象超类一起使用会导致使用 Hibernate 和 MySQL 的 Spring 应用程序出现问题?的详细内容。更多信息请关注PHP中文网其他相关文章!