gpt4 book ai didi

java - JPA - 如果不存在则创建实体?

转载 作者:IT老高 更新时间:2023-10-28 20:41:29 25 4
gpt4 key购买 nike

我的 JPA/Hibernate 应用程序中有几个映射对象。在网络上,我收到代表这些对象更新的数据包,或者实际上可能完全代表新对象。

我想写一个类似的方法

<T> T getOrCreate(Class<T> klass, Object primaryKey)

如果一个对象存在于数据库中,则返回所提供类的对象,使用 pk primaryKey,否则创建该类的新对象,将其持久化并返回。

接下来我将对对象执行的操作是在事务中更新其所有字段。

在 JPA 中有没有一种惯用的方法来做到这一点,或者有没有更好的方法来解决我的问题?

最佳答案

I'd like to write a method like <T> T getOrCreate(Class<T> klass, Object primaryKey)

这并不容易。

一种天真的方法是做这样的事情(假设该方法在事务中运行):

public <T> T findOrCreate(Class<T> entityClass, Object primaryKey) {
T entity = em.find(entityClass, primaryKey);
if ( entity != null ) {
return entity;
} else {
try {
entity = entityClass.newInstance();
/* use more reflection to set the pk (probably need a base entity) */
return entity;
} catch ( Exception e ) {
throw new RuntimeException(e);
}
}
}

但在并发环境中,此代码可能会由于某些竞争条件而失败:

T1: BEGIN TX;T2: BEGIN TX;T1: SELECT w/ id = 123; //returns nullT2: SELECT w/ id = 123; //returns nullT1: INSERT w/ id = 123;T1: COMMIT; //row insertedT2: INSERT w/ name = 123;T2: COMMIT; //constraint violation

如果您正在运行多个 JVM,同步将无济于事。如果没有获得表锁(这非常可怕),我真的不知道你怎么能解决这个问题。

在这种情况下,我想知道是否最好先系统地插入并处理可能的异常以执行后续选择(在新事务中)。

您可能应该添加一些有关上述约束的详细信息(多线程?分布式环境?)。

关于java - JPA - 如果不存在则创建实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3562105/

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