什么时候可以抛出NoSuchResult

时间:2018-01-25 14:35:57

标签: java postgresql hibernate jpa

我继承了一个系统,其中有一个相当奇怪的错误,可能每6个月发生一次,应用程序突然失去对数据库数据的跟踪。

系统具有2个服务器的冗余,这些服务器被安排为同时运行相同的功能。它们都为函数提供相同的输入数据,并且它们都与同一个postgres数据库通信,但是这两台机器上的行为是不同的。

正在执行的函数是调用数据库并检查输入参数是否存在具有指定标识的行,如果存在,则执行A(),否则B()

问题是一台服务器执行A()而另一台B()。我到处搜索,没有代码写入此表或从中删除。所以我认为他们都应该执行相同的代码。

这是从数据库中提取的代码:

@PersistenceContext(unitName = "backend-persistence")
private EntityManager em;
public Optional<OfferEntity> getOfferFromOfferId(final long offerId, final String countryAlias, final String langauageAlias) {

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<OfferEntity> cq = cb.createQuery(OfferEntity.class);
    Root<OfferEntity> from = cq.from(OfferEntity.class);
    cq.select(from);
    cq.where(cb.and(cb.equal(from.get(OfferEntity_.offerId), offerId),
            cb.equal(from.get(OfferEntity_.country), countryAlias),
            cb.equal(from.get(OfferEntity_.language), langauageAlias)));

    try {

        return Optional.of(em.createQuery(cq).getSingleResult());
    } catch (NoResultException nre) {

        return Optional.empty();
    }
}

我从其中一个服务器获得一个空的可选项,但不是另一个服务器。

所以我想作为一个tl;博士,我是否想念NoResultException以及在什么具体情况下可以抛出它?此外,如果没有与查询匹配的行。

1 个答案:

答案 0 :(得分:1)

当您确定只能获得一个结果时,您只能使用getSingleResult()。在所有其他情况下,您必须使用getResultList()

来自javax.persistence.Query的API文档getSingleResult():

java.lang.Object getSingleResult()

Execute a SELECT query that returns a single untyped result.

Returns:
the result

Throws:
NoResultException - if there is no result
NonUniqueResultException - if more than one result
IllegalStateException - if called for a Java Persistence query language UPDATE or DELETE statement
QueryTimeoutException - if the query execution exceeds the query timeout value set and only the statement is rolled back
TransactionRequiredException - if a lock mode has been set and there is no transaction
PessimisticLockException - if pessimistic locking fails and the transaction is rolled back
LockTimeoutException - if pessimistic locking fails and only the statement is rolled back
PersistenceException - if the query execution exceeds the query timeout value set and the transaction is rolled back