Hibernate委托将UUID生成任务交给PostgreSQL。

huangapple go评论83阅读模式
英文:

Hibernate to delegate UUID generation to postgres

问题

I understand that you want the translation of the code portions from your provided text. Here they are:

  1. <databaseChangeLog
  2. xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
  5. <changeSet author="..." id="uuid-ossp-extension">
  6. <sql>CREATE EXTENSION IF NOT EXISTS "uuid-ossp"</sql>
  7. </changeSet>
  8. <changeSet author="example" id="widgets-table">
  9. <createTable tableName="widgets">
  10. <column name="widget_id" type="uuid" defaultValueComputed="uuid_generate_v1mc()">
  11. <constraints nullable="false" primaryKey="true" primaryKeyName="widget_pk"/>
  12. </column>
  13. <column name="name" type="varchar(10)">
  14. <constraints nullable="false"/>
  15. </column>
  16. </createTable>
  17. </changeSet>
  18. </databaseChangeLog>
  1. @Repository
  2. @RequiredArgsConstructor
  3. public class WidgetRepository {
  4. public static final String INSERT_QUERY = "INSERT INTO widgets(name) VALUES (:name)";
  5. private final NamedParameterJdbcTemplate template;
  6. public UUID saveAndReturn(Widget widget) {
  7. var params = new MapSqlParameterSource(Map.of("name", widget.getName());
  8. var generatedKeyHolder = new GeneratedKeyHolder();
  9. var generateKeyColumns = new String[]{"widget_id"};
  10. template.update(INSERT_QUERY, params, generatedKeyHolder, generateKeyColumns);
  11. return generatedKeyHolder.getKeyAs(UUID.class);
  12. }
  13. ...
  14. }
  1. @Entity
  2. @Table(name = "widgets")
  3. public class Widget {
  4. @Id
  5. @UuidGenerator(style = TIME)
  6. @Column(name = "widget_id")
  7. private UUID id;
  8. @Column
  9. private String name;
  10. ...
  11. }

Please note that I've replaced some special characters used for HTML/XML encoding in your provided code with their respective characters for readability.

英文:

Imagine I have a simple table such as the following, defined using a liquibase changeset

  1. <databaseChangeLog
  2. xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
  5. <changeSet author="..." id="uuid-ossp-extension">
  6. <sql>CREATE EXTENSION IF NOT EXISTS "uuid-ossp"</sql>
  7. </changeSet>
  8. <changeSet author="example" id="widgets-table">
  9. <createTable tableName="widgets">
  10. <column name="widget_id" type="uuid" defaultValueComputed="uuid_generate_v1mc()">
  11. <constraints nullable="false" primaryKey="true" primaryKeyName="widget_pk"/>
  12. </column>
  13. <column name="name" type="varchar(10)">
  14. <constraints nullable="false"/>
  15. </column>
  16. </createTable>
  17. </changeSet>
  18. </databaseChangeLog>

That is, I want to be explicit about letting postgres compute the UUID.

If I was using Spring JdbcTemplate, I could use something simple like:

  1. @Repository
  2. @RequiredArgsConstructor
  3. public class WidgetRepository {
  4. public static final String INSERT_QUERY = "INSERT INTO widgets(name) VALUES (:name)";
  5. private final NamedParameterJdbcTemplate template;
  6. public UUID saveAndReturn(Widget widget) {
  7. var params = new MapSqlParameterSource(Map.of("name", widget.getName());
  8. var generatedKeyHolder = new GeneratedKeyHolder();
  9. var generateKeyColumns = new String[]{"widget_id"};
  10. template.update(INSERT_QUERY, params, generatedKeyHolder, generateKeyColumns);
  11. return generatedKeyHolder.getKeyAs(UUID.class);
  12. }
  13. ...
  14. }

With Hibernate 6.0 onwards, there is a new UuidGenerator annotation, that simplifies Hibernate taking responsibility for generating a UUID:

  1. @Entity
  2. @Table(name = "widgets")
  3. public class Widget {
  4. @Id
  5. @UuidGenerator(style = TIME)
  6. @Column(name = "widget_id")
  7. private UUID id;
  8. @Column
  9. private String name;
  10. ...
  11. }

However, this new UUIDGenerator mechanism doesn't seem to support delegating to postgres. https://vladmihalcea.com/uuid-identifier-jpa-hibernate/ suggested an alternative approach, but the UUIDGenerationStrategy it implements is now deprecated.

Does anyone know the preferred mechanism for Hibernate 6.0 onwards?

答案1

得分: 2

I tweeted about this here:

<https://twitter.com/1ovthafew/status/1645795161379831811>

The short answer is:

  1. @Entity
  2. public class Entity {
  3. @Generated @Id
  4. @ColumnDefault(&quot;gen_random_uuid()&quot;)
  5. UUID uuid;
  6. }

Note that Hibernate 6.2 is required.

英文:

I tweeted about this here:

<https://twitter.com/1ovthafew/status/1645795161379831811>

The short answer is:

  1. @Entity
  2. public class Entity {
  3. @Generated @Id
  4. @ColumnDefault(&quot;gen_random_uuid()&quot;)
  5. UUID uuid;
  6. }

Note that Hibernate 6.2 is required.

huangapple
  • 本文由 发表于 2023年5月10日 16:09:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76216222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定