何时会抛出NoSuchResult异常?

4
我接手了一个系统,其中存在一个相当奇怪的错误,可能每六个月才会出现一次,即应用程序突然丢失对数据库数据的跟踪。
该系统具有两台服务器的冗余,它们被安排在同一时间运行相同的功能。它们都获得相同的输入数据到函数,并且它们都与同一个PostgreSQL数据库通信,但是这两台机器的行为不同。
正在执行的函数调用数据库并检查是否存在指定ID的行作为输入参数提供,并且如果存在,则执行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();
    }
}

我从其中一台服务器得到了一个空的可选项,但是没有从另一个服务器得到。

因此,简单来说,我是否误解了NoResultException,在什么具体情况下可以抛出它?除了查询中没有匹配行之外。


http://www.datanucleus.org/javadocs/javax.persistence/2.2/javax/persistence/Query.html#getSingleResult-- - user8558216
@DN1 我非常清楚,但是"如果没有结果"的定义是什么呢?我认为这相当模糊,因为它可能是"没有匹配查询的行"或者"数据库抛出了一个错误,所以没有结果",或者可能是其他情况。 - munHunger
1
这一点并不含糊。JPA将getSingleResult方法返回的缺失结果视为异常情况,这是因为它本来就应该与必然只产生一个结果的查询(例如聚合查询)一起使用。对于“根据我的业务逻辑可能永远不会有多个结果”的查询,getSingleResult方法并不是一个好的选择,你应该使用getResultList方法。 - crizzis
不同的库版本会让人想起。 - Joop Eggen
1
是的。话虽如此,“NoResultException”显然并不意味着数据库抛出异常的情况。您所经历的可能是Postgres JDBC驱动程序的错误,或者(我认为这种可能性较小)缓存配置错误。 - crizzis
显示剩余2条评论
1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接