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

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

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:

<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
 
    <changeSet author="..." id="uuid-ossp-extension">
        <sql>CREATE EXTENSION IF NOT EXISTS "uuid-ossp"</sql>
    </changeSet>
 
    <changeSet author="example" id="widgets-table">
        <createTable tableName="widgets">
            <column name="widget_id" type="uuid" defaultValueComputed="uuid_generate_v1mc()">
                <constraints nullable="false" primaryKey="true" primaryKeyName="widget_pk"/>
            </column>
            <column name="name" type="varchar(10)">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>
 
</databaseChangeLog>
@Repository
@RequiredArgsConstructor
public class WidgetRepository {

    public static final String INSERT_QUERY = "INSERT INTO widgets(name) VALUES (:name)";


    private final NamedParameterJdbcTemplate template;

    public UUID saveAndReturn(Widget widget) {
        var params = new MapSqlParameterSource(Map.of("name", widget.getName());
        var generatedKeyHolder = new GeneratedKeyHolder();
        var generateKeyColumns = new String[]{"widget_id"};
        template.update(INSERT_QUERY, params, generatedKeyHolder, generateKeyColumns);
        return generatedKeyHolder.getKeyAs(UUID.class);
    }

    ...

}
@Entity
@Table(name = "widgets")
public class Widget {
 
    @Id
    @UuidGenerator(style = TIME)
    @Column(name = "widget_id")
    private UUID id;
 
    @Column
    private String name;

    ...
}

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

<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
 
    <changeSet author="..." id="uuid-ossp-extension">
        <sql>CREATE EXTENSION IF NOT EXISTS "uuid-ossp"</sql>
    </changeSet>
 
    <changeSet author="example" id="widgets-table">
        <createTable tableName="widgets">
            <column name="widget_id" type="uuid" defaultValueComputed="uuid_generate_v1mc()">
                <constraints nullable="false" primaryKey="true" primaryKeyName="widget_pk"/>
            </column>
            <column name="name" type="varchar(10)">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>
 
</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:

@Repository
@RequiredArgsConstructor
public class WidgetRepository {

    public static final String INSERT_QUERY = "INSERT INTO widgets(name) VALUES (:name)";


    private final NamedParameterJdbcTemplate template;

    public UUID saveAndReturn(Widget widget) {
        var params = new MapSqlParameterSource(Map.of("name", widget.getName());
        var generatedKeyHolder = new GeneratedKeyHolder();
        var generateKeyColumns = new String[]{"widget_id"};
        template.update(INSERT_QUERY, params, generatedKeyHolder, generateKeyColumns);
        return generatedKeyHolder.getKeyAs(UUID.class);
    }

    ...

}

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

@Entity
@Table(name = "widgets")
public class Widget {
 
    @Id
    @UuidGenerator(style = TIME)
    @Column(name = "widget_id")
    private UUID id;
 
    @Column
    private String name;

    ...
}

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:

@Entity
public class Entity {
    @Generated @Id
    @ColumnDefault(&quot;gen_random_uuid()&quot;)
    UUID uuid;
}

Note that Hibernate 6.2 is required.

英文:

I tweeted about this here:

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

The short answer is:

@Entity
public class Entity {
    @Generated @Id
    @ColumnDefault(&quot;gen_random_uuid()&quot;)
    UUID uuid;
}

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:

确定