gpt4 book ai didi

hibernate - JPA 中的自定义主键生成器

转载 作者:行者123 更新时间:2023-12-02 22:51:08 29 4
gpt4 key购买 nike

我正在使用 org.hibernate.id.IdentifierGenerator 生成主键列,如下所示。在下面给出的示例中,目前它只是按顺序递增 INT(11) 类型的键(MySQL),即它确实像 MySQL 中的 auto_increment 但它可以用于生成任何自定义模式的值,例如 E0001、E0002、E0003 ... E0010 ... E0100 ... E1000 ... E12345 ...

import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IdentifierGenerator;

public final class TestIdGenerator implements IdentifierGenerator {

@Override
public Serializable generate(SessionImplementor session, Object object) throws HibernateException {

try {
Connection connection = session.connection();
PreparedStatement ps = connection.prepareStatement("SELECT MAX(id) AS id FROM test");
ResultSet rs = ps.executeQuery();

if (rs.next()) {
int id = rs.getInt("id");
return id <= 0 ? 1 : id + 1;
}
} catch (SQLException e) {
e.printStackTrace();
}

return null;
}
}

使用上述 id 生成器的实体 Test :

public class Test implements Serializable {

@Id
@GenericGenerator(name = "test_sequence", strategy = "com.example.TestIdGenerator")
@GeneratedValue(generator = "test_sequence")
@Basic(optional = false)
@Column(name = "id", nullable = false)
private Integer id;

//...
}

然而,这是 Hibernate 的特定功能。有没有办法使其与提供者无关,即 JPA (2.1) 中是否有此类功能?

我使用的是带有 JPA 2.1 的 Hibernate 5.1.0 Final。

<小时/>

这种方法在持久化、合并和删除实体时是否会导致一些并发问题并需要某种锁定?

最佳答案

您无法像您希望的那样使用注释来完成此操作。您可以使用@PrePersist Hook 。

@PrePersist
public void ensureId() {
id = ...
}

也就是说,您可能无法从 @PrePersist 方法访问数据库...JPA 2 规范 (JSR 317) 声明如下:

In general, the lifecycle method of a portable application should not invoke EntityManager or Query operations, access other entity instances, or modify relationships within the same persistence context.

就实现而言,Hibernate 明确禁止它:

A callback method must not invoke EntityManager or Query methods!

我的建议:如果需要指定类型,请使用序列并使用单独的列。此外,您始终可以修改 SELECT 来拉回您选择的模式:

select 'E' || id as id from schema.table;

或者你可以使用@PostLoad/@PostPersist来拉回一个Transient字段“formattedId”:

@PostLoad
@PostPersist
private void setFormattedId() {
this.formattedId = "E" + id;
}

关于hibernate - JPA 中的自定义主键生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37160332/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com