Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程应用程序的Hibernate getOrCreate模式_Java_Hibernate - Fatal编程技术网

Java 多线程应用程序的Hibernate getOrCreate模式

Java 多线程应用程序的Hibernate getOrCreate模式,java,hibernate,Java,Hibernate,我已经搜索了一段时间,但还没有找到一个我正在尝试做的例子 我们有一个将被大量使用的API。其中一个操作是创建一个新的客户端域对象。每个客户端的名称都是唯一的 在下面的代码中,我们按名称读取客户机。如果它不存在,我们尝试创建它。由于两个线程可能同时尝试创建同一个客户端,因此我们捕获一个ConstraintException,然后执行另一个查找,以防另一个线程在我们之前进入: @Transactional(propagation = Propagation.REQUIRES_NEW, readOn

我已经搜索了一段时间,但还没有找到一个我正在尝试做的例子


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

在下面的代码中,我们按名称读取客户机。如果它不存在,我们尝试创建它。由于两个线程可能同时尝试创建同一个客户端,因此我们捕获一个
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对此代码表示不满,因为在异常中,我们试图使用异常中涉及的会话:

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

是否有一种标准模式或方法来完成我在Hibernate中尝试执行的操作?

您只需将捕获和重试移出事务,即可使用新事务(和会话):

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;
}