gpt4 book ai didi

java - 多线程应用程序的 Hibernate getOrCreate 模式

转载 作者:行者123 更新时间:2023-11-30 09:18:58 26 4
gpt4 key购买 nike

我已经搜索了一段时间,但没有找到我正在尝试做的事情的示例。


我们有一个将被大量使用的 API。其中一项操作是创建一个新的 Client 域对象。每个 Client 的名称都是唯一的。

在下面的代码中,我们通过名称读取客户端。如果它不存在,我们尝试创建它。由于 2 个线程可能会同时尝试创建相同的客户端,因此我们捕获了一个 ConstraintException,然后进行另一次查找,以防另一个线程在我们之前进入:

@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, isolation = Isolation.READ_COMMITTED)
public Client getOrCreate(String name) {
DetachedCriteria query = DetachedCriteria.forClass(Client.class).add(Restrictions.eq("name", name));

Client client = entityDao.findSingle(Client.class, query);

if (client == null) {
client = new Client();
client.setName(name);
try {
entityDao.save(client);
} catch (ConstraintViolationException e) {
client = entityService.findSingle(Client.class, query);
}
}
return client;
}

Hibernate 提示这段代码,因为在异常中我们试图使用一个涉及异常的 session :

org.hibernate.AssertionFailure: null id in com.mydomain.Client entry (don't flush the Session after an exception occurs)

是否有标准模式或方法来完成我在 Hibernate 中尝试做的事情?

最佳答案

您只需要将 catch 和 retry 移出事务,以便使用新事务(和 session ):

Client client;
try {
client = clientService.getOrCreate(name);
}
catch (ConstraintViolationException e) {
client = clientService.getOrCreate(name);
}

@Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = false, isolation = Isolation.READ_COMMITTED)
public Client getOrCreate(String name) {
DetachedCriteria query =
DetachedCriteria.forClass(Client.class).add(Restrictions.eq("name", name));

Client client = entityDao.findSingle(Client.class, query);

if (client == null) {
client = new Client();
client.setName(name);
entityDao.save(client);
}
return client;
}

关于java - 多线程应用程序的 Hibernate getOrCreate 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18207797/

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