java - 使用非自动生成的 ID 保存在 JPA/Hibernate 中的替代方法
问题描述
我正在尝试将一个值插入到 ID 中为 String 类型的数据库中。
@Entity
@Table(name = "xpto_version_map")
public class XptoVersionMap implements Serializable {
@Id
@Column(name = "uniq_name", unique = true, nullable = false)
private String uniq_name;
...
尝试保存新的 XptoVersionMap() 时,例如:
XptoVersionMap xptoVersionMap = new XptoVersionMap();
xptoVersionMap.setUniqName("XPTO-1");
xptoVersionMap.setValue("value2");
xptoVersionMapRepository.save(xptoVersionMap);
会抛出:
org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find xxx.api.database.entity.XptoVersionMap with id XPTO-1; nested exception is javax.persistence.EntityNotFoundException: Unable to find xxx.api.database.entity.XptoVersionMap with id XPTO-1.
我尝试了不同的解决方案,但除非我可以进行本机查询来插入值,否则我无法告诉 Hibernate 我只想检查 @Id (uniq_name) 是否存在,如果不插入新的值而不是抛出异常。
解决方案
这就是 Hibernate 默认的工作方式。当您执行保存方法并且未设置 ID 时,它会分配一个自动生成的 ID。如果有一个 ID,它会尝试更新它(在你的情况下会发生什么)。
保存实体。如果不存在,将分配一个标识符。如果是这样,它本质上是在进行更新。返回生成的实体 ID。
例如,您可以通过使用 persist 和 @PrePersist 来解决问题
@PrePersist
void generateId() {
if (uniq_name == null) {
uniq_name = GENERATE_SOME_UNIQUE_ID_SO_IT_DOESN'T_BREAK();
}
}
然后使用 xptoVersionMapRepository.persist(xptoVersionMap);
或者你可以用类似的东西编写你自己的生成器:
@GenericGenerator(name = "my_generator", strategy = "package.CustomGenerator")
@GeneratedValue(generator = "my_generator")
然后创建一个实现 IdentifierGenerator 的类 CustomGenerator 并创建所需的方法。
推荐阅读
- sql - 每个基金和客户需要的平均值
- amazon-web-services - 在 terragrunt 配置中使用变量
- javascript - Laravel 8 在视图中显示数据并将数据发送到数据库
- json - 使用 shell 脚本动态更新 ecs taskdef.json 中的键值
- javascript - 我想通过单击跨度来循环显示纯文本下划线和换行
- svg - Mapbox - 如何在缩放时阻止填充模式乘以/拆分 SVG 图像
- javascript - 我如何在 discord.js 中修复此嵌入消息。我使用了命令处理程序
- sql - Django 主查询按子查询排序
- php - mysql结果循环中的php电子邮件
- html - 使用jquery ui时如何限制调整大小区域