postgresql - Spring Boot Hibernate 使用序列或身份生成实体 ID 的问题
问题描述
我使用 sprint boot、jpa、hibernate 和 PostgreSQL 开发了 Rest API。我的目标是能够生成自动递增的 id,以便与代码一起使用并使用 D Beaver 等数据库工具,而无需编写任何额外的查询来获取下一个 ID 值等。
我创建了实体User
。我尝试通过两种方式生成 id:
- GenerationType.IDENTITY
使用 GenerationType.IDENTITY 时,它成功地创建了带有名称的表、带有名称user
的序列并为columnuser_id_seq
添加了默认值。数据库中的所有内容都符合预期,并且与数据库工具配合得很好,但是当我尝试从我的 API 插入新行时会出现问题。尝试插入新行时休眠执行查询user.id
nextval('user_id_seq'::regclass)
select currval('user_id_seq')
获取 id 值,我收到错误
org.postgresql.util.PSQLException: ERROR: invalid name syntax
因为周围的那些报价user
。它应该执行
select currval('user_id_seq')
我相信这里的问题是因为我使用user
了作为保留关键字的表名,但我想保持这种方式,因为这个命名与其他表模式匹配。
- GenerationType.SEQUENCE
如果我使用注释:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_generator")
@SequenceGenerator(name="user_generator", sequenceName = "user_id_seq", allocationSize=1)
它创建表'user',序列'user_id_seq'但不添加user.id列默认值,所以我不能使用数据库工具插入新行而不指定id值。但是使用这一代类型我的 API 工作正常。
还值得一提的是,我spring.jpa.hibernate.ddl-auto=create-drop
每次都使用并手动删除和重新创建模式,因此不会留下任何不必要的序列/表。
@Entity
@Table(name = "`user`")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// other properties...
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// other getters and setters...
}
所以......有可能以某种方式连接这两种方式并创建一个可行的解决方案吗?我需要为列设置默认值,并且休眠也知道如何生成该 ID。
PS 我不想在运行应用程序时更改表/实体命名或执行 SQL 以更正表。我相信应该有更好的方法。
解决方案
经过数小时的调试后,我最终扩展了 PostgreSQL82Dialect 并覆盖了 getIdentitySelectString 函数以从表名中删除引号。
推荐阅读
- php - 使用 Ionic httpClient POST 到 PHP API 不发送任何数据
- angular - 我可以为 angular/typescript 中的导入库提供别名吗?
- intellij-idea - 如何在 IntelliJ 项目中添加新包?
- speech-recognition - 不能识别除英语以外的其他语言的句子
- android - 在布局 xml 中定义 Android 标签不起作用
- c - 如何在cmake窗口中添加资源
- amazon-web-services - 通过网关 websocket 调用长时间运行的 Lambda 的最简单方法是什么?
- c++ - 尝试初始化静态方法时出现错误“方法在此上下文中是私有的”
- swift - iOS GCD 同步和异步
- python-3.x - AxisError:轴 1 超出维度 1 数组的范围 - np.concatenate()