4

假设我有一些这样的代码:

Vehicle vehicle = vehicleRepostory.findByIdInitialized(vehicleId);

如果Vehicle找不到此方法将返回null。规范说在这种情况下我必须抛出一个MyObjectNotFoundException所以代码变成这样:

Vehicle vehicle = vehicleRepostory.findByIdInitialized(vehicleId);
MyObjectNotFoundException.throwIfNull(vehicle, Vehicle.class, vehicleId);

如果我想摆脱对throwIfNull. 无论如何,它并不是真正的干燥和糟糕的设计选择。一定有一些我不知道的设计模式。我在网上搜索,但没有找到任何真正有用的东西。

一个简单的解决方案可能是将代码放入我的存储库中,但我为此使用 SpringData,因此它只是一个接口:

public interface VehicleRepository extends Repository<Vehicle, Long>

// ...

@Query("select v from Vehicle v LEFT JOIN FETCH v.technicalData td LEFT JOIN FETCH v.registrationData rd"
    + " where v.vehicleId = ?")
Vehicle findByIdInitialized(Long vehicleId);
4

7 回答 7

3

听起来您基本上希望您的存储库支持这一点:

Vehicle vehicle = vehicleRepository.loadExisting(vehicleId);

loadExisting和之间的区别在于findByIdInitialized前者期望实体存在,如果不存在则抛出异常。

这样,所有存储库客户端都可以决定在执行查找时是否希望缺少实体导致异常。您甚至可能会发现所有按 ID 进行的查找都应该引发异常——在这种情况下,您可以返回使用单一方法。

编辑:如果存储库是自动生成的,我将采用以下三种方法之一:

  • 把它包起来
  • 扩展它
  • 修改生成器

这些选择中的哪一个最合适将取决于确切的细节。

于 2013-02-22T09:44:57.587 回答
0

您可以查看 Java 中的 @NotNull 注释。它有几种风格,其中一些在编译时进行验证,其中一些在运行时进行。当您执行可能导致 NPE 的操作时,一些编辑器(例如 IntelliJ IDEA)会警告您。

我应该使用哪个 @NotNull Java 注释? 避免 != null 语句 http://docs.oracle.com/javaee/6/api/javax/validation/constraints/NotNull.html

于 2013-02-22T09:43:39.617 回答
0

用这个:

import static java.util.Objects.requireNonNull;

.
.
.

Object o = requireNonNull(obj);
于 2013-02-22T09:47:49.460 回答
0

听起来你想要“在方法返回之后”AOP 建议,它拦截空值并抛出异常。

于 2013-02-22T09:48:41.893 回答
0

如果您可以重新设计存储库本身以抛出您需要的异常,那当然是最好的。没有它,您需要修补行为的解决方法。

一种方法是反射:将调用包装在一个以字符串形式repository接收并以反射方式调用它的方法中。findByIdInitialized然后该方法可以抛出适当的异常。

另一种方法可能是让一些 AOP 来做同样的事情,但可能具有更多的类型安全性。

于 2013-02-22T09:44:52.433 回答
0

我建议您在 findByIdInitialized 中添加一个可为空的参数,它会像:

Vehicle findByIdInitialized(int vehicleId, boolean throwException) {
   // implementation behavior...

   if (throwException) {
       MyObjectNotFoundException.throwIfNull(vehicle, Vehicle.class, vehicleId);
   }
}
于 2013-02-22T09:47:00.063 回答
-2

您可以使用NullObject设计模式,但抛出异常恕我直言是最好的选择。

为了保持干燥,你应该把那个扔进去findbyIdInitialized

于 2013-02-22T09:42:56.740 回答