使用Spring Data获取单个NonNull值

时间:2016-01-16 11:00:18

标签: java spring spring-data spring-data-jpa

我想在我的Repository中有一个返回单个值的方法。 像这样:

TrainingMode findByTrainingNameAndNameEng( String trainingName, String nameEng );

http://docs.spring.io/spring-data/data-jpa/docs/current/reference/html/ Spring Data Docs描述了在这种情况下,如果没有找到实体,该方法可以返回null。 我想抛出像No TrainingMode found by %trainingName% and %nameEng%这样的通用消息或像这样的smth的异常。

我可以使用Optional<TrainingMode>作为返回值,然后使用orElseThrow

Optional<TrainingMode> findByTrainingNameAndNameEng( String trainingName, String nameEng );

repository.findByTrainingNameAndNameEng(name, nameEng).orElseThrow(() -> new RuntimeException(...));

但每次调用此方法时都应该调用此方法。目前尚不清楚 - DRY原则已被打破。

如何使用Spring Data使用orElseThrow获取非空单值?

3 个答案:

答案 0 :(得分:1)

如果在整个调用它的应用程序逻辑中复制空值处理,则会违反DRY原则。如果DRY原则是您最担心的事情,那么我可以想到:

  1. 您可以制作一个&#34;服务&#34;将调用委托给带注释的存储库并对其处理空响应逻辑的类,并使用该服务类而不是直接调用存储库。缺点是会为您的应用程序引入另一个层(这会将存储库与您的应用程序逻辑分离)。

  2. 有可能在您的数据存储库中添加自定义行为,这些行为在&#34; 3.6.1. Adding custom behavior to single repositories&#34;文档部分。很抱歉没有发布代码段。

  3. 我个人对第二种方法的问题是它污染了带有接口的app,强制你遵循某种命名模式(从不喜欢&#39; Impl&#39;后缀),并且可能会使代码迁移更多时间消费(当app变大时,跟踪哪个界面负责哪个自定义行为变得更难,然后人们只是简单地开始创建他们自己的行为,结果证明是另一个的重复)。

答案 1 :(得分:1)

我找到了解决方案。

首先,Spring Data处理getByName和findByName。我们可以使用它:在我的情况下,find *可以返回null(或者返回not null可选,如你所愿)和get *应该只返回值:如果返回null则抛出异常。

我决定在这种情况下使用AOP。 这是方面:

@Aspect
@Component
public class GetFromRepositoryAspect {
    @Around("execution(public !void org.springframework.data.repository.Repository+.get*(..))")
    public Object aroundDaoMethod( ProceedingJoinPoint joinpoint ) throws Throwable {
        Object result = joinpoint.proceed();
        if (null == result) {
            throw new FormattedException( "No entity found with arhs %s",
                    Arrays.toString( joinpoint.getArgs() ) );
        }
        return result;
    }
}

就是这样。

答案 2 :(得分:1)

您可以使用Spring nullability annotations来实现。如果方法的返回类型只是某些Entity而不是包装类型,例如Optional<T>,则在无结果的情况下将抛出org.springframework.dao.EmptyResultDataAccessException

详细了解Null Handling of Repository Methods