假设我有一些这样的代码:
Vehicle vehicle = vehicleRepostory.findByIdInitialized(vehicleId);
如果找不到Vehicle
,则此方法将返回null
。规范说在这种情况下我必须抛出MyObjectNotFoundException
所以代码变成这样:
Vehicle vehicle = vehicleRepostory.findByIdInitialized(vehicleId);
MyObjectNotFoundException.throwIfNull(vehicle, Vehicle.class, vehicleId);
如果我想摆脱对throwIfNull
的调用,我该怎么办?无论如何,它并不是真正的DRY和糟糕的设计选择。必须有一些我不知道的设计模式。我在网上搜索过,但没有找到真正有用的东西。
一个简单的解决方案可能是将代码放入我的存储库,但我使用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);
答案 0 :(得分:3)
听起来基本上你希望你的存储库支持这个:
Vehicle vehicle = vehicleRepository.loadExisting(vehicleId);
loadExisting
和findByIdInitialized
之间的区别在于前期望实体存在,如果不存在则会抛出异常。
这样,所有存储库客户端都可以决定是否在执行查找时,他们是否希望缺少实体来导致异常。您甚至可能会发现ID中的所有查找都会引发异常 - 在这种情况下,您可以返回使用单个方法。
编辑:如果存储库是自动生成的,我将采用以下三种方法之一:
哪种选择最合适取决于具体细节。
答案 1 :(得分:0)
您可以在Java中查看@NotNull注释。它有几种风格,其中一些在编译时进行验证,其中一些在运行时进行。某些编辑器(如IntelliJ IDEA)可以在您进行可能导致NPE的操作时发出警告。
Which @NotNull Java annotation should I use? Avoiding != null statements http://docs.oracle.com/javaee/6/api/javax/validation/constraints/NotNull.html
答案 2 :(得分:0)
如果您可以重新设计存储库本身以抛出所需的异常,那当然是最好的。如果没有这个,你需要修补行为的解决方法。
一种方法是反射:在一个接收repository
作为字符串并以反射方式调用它的方法中调用findByIdInitialized
。然后该方法可以抛出适当的异常。
另一种方法可能是让一些AOP做同样的事情,但也许更安全。
答案 3 :(得分:0)
我建议你为findByIdInitialized添加一个可以为null的参数,它就像:
Vehicle findByIdInitialized(int vehicleId, boolean throwException) {
// implementation behavior...
if (throwException) {
MyObjectNotFoundException.throwIfNull(vehicle, Vehicle.class, vehicleId);
}
}
答案 4 :(得分:0)
使用此:
import static java.util.Objects.requireNonNull;
.
.
.
Object o = requireNonNull(obj);
答案 5 :(得分:0)
听起来像你想要&#34;方法返回&#34; AOP建议,拦截空值并抛出异常。
答案 6 :(得分:-2)
您可以使用NullObject设计模式,但抛出异常IMHO是最佳选择。
要保持DRY,你应该把它扔进findbyIdInitialized
。