【发布时间】:2019-11-23 12:04:36
【问题描述】:
我使用 sprint boot、jpa、hibernate 和 PostgreSQL 开发了 Rest API。我的目标是能够生成自动递增的 id,以便与代码一起使用并使用 D Beaver 等数据库工具,而无需编写任何额外的查询来获取下一个 ID 值等。
我创建了实体User。我尝试通过两种方式生成 id:
- GenerationType.IDENTITY
当使用 GenerationType.IDENTITY 时,它成功创建了名称为 user 的表,名称为 user_id_seq 的序列,并为 user.id 列 nextval('user_id_seq'::regclass) 添加了默认值。数据库中的所有内容都符合预期,并且与数据库工具配合得很好,但是当我尝试从我的 API 插入新行时会出现问题。当尝试插入新行时休眠执行查询
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...
}
那么...有可能以某种方式将这两种方式联系起来并创建一个可行的解决方案吗?我需要为 column 设置默认值,并且 hibernate 也知道如何生成该 id。
附:我不想在运行应用程序时更改表/实体命名或执行 SQL 以更正表。我相信应该有更好的方法。
【问题讨论】:
标签: postgresql hibernate spring-boot spring-data-jpa