我对Postgres和GenerationType.Identity vs Sequence
有疑问在这个例子中......
@Id
@SequenceGenerator(name="mytable_id_seq",
sequenceName="mytable_id_seq",
allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,
generator="mytable_id_seq")
据我所知,我正在通过注释指定Postgres序列。
但是,我有一个用'serial'类型定义的id列,我读过我可以简单地使用GenerationType.IDENTITY,它会自动生成一个db序列并用它来自动递增。
如果是这种情况,我看不到使用SEQUENCE注释的优势,除非您使用id的整数或者有一些特定的理由使用您创建的其他序列。 IDENTITY的代码很少,并且可能使其在数据库中可移植。
有什么我想念的吗?
提前感谢您的反馈。
答案 0 :(得分:12)
如果您有SERIAL
类型的列,则只需使用以下内容注释id
字段即可:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
这告诉Hibernate数据库将负责生成id
列。数据库如何实现自动生成是特定于供应商的,可以被认为是“透明的”#34;到Hibernate。 Hibernate只需知道在插入行之后,该行的id
值将以某种方式检索。
如果使用GenerationType.SEQUENCE
,您告诉Hibernate数据库不会自动填充id
列。相反,Hibernate负责从指定的序列中获取下一个序列值,并在插入行时将其用作id
值。所以Hibernate正在生成并插入id
。
对于Postgres,通过创建序列并将其用作默认列值来实现定义SERIAL
列。但是填充id
字段的是数据库,因此使用GenerationType.IDENTITY
告诉Hibernate数据库正在处理id生成。
这些参考资料可能有所帮助:
https://www.postgresql.org/docs/8.1/static/datatype.html#DATATYPE-SERIAL
答案 1 :(得分:0)
我认为如果您对多个表使用相同的序列(例如,您希望许多类型的帐单具有唯一标识符),这会很有帮助...还有如果您想要跟踪序列自动生成的密钥
答案 2 :(得分:0)
摘自“ Pro JPA2”书:
”使用IDENTITY和其他id生成策略之间的另一个区别是,之前暗示的是,直到插入发生后,标识符才可访问。尽管不能保证在交易完成之前标识符的可访问性,至少其他类型的生成可能会急切地分配标识符,但是当使用身份时,插入操作会导致标识符的生成,而标识符在实体出现之前是不可能的。插入到数据库中,并且由于实体的插入通常会推迟到提交时间之后,因此标识符直到事务提交后才可用。”
答案 3 :(得分:0)
您可以找到 here 相应地更新 PostgreSQL 表创建的解决方案,以便与 GenerationType.IDENTITY 选项配合使用。