Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to throw exceptions on search methods in spring data jpa

I am using spring-data-jpa repositories for database operations. I want to throw exceptions if object doesn't exists in database for all methods in my repositories. For example Consider the following method in OrderRepository

findByCustomerAndPayment(Customer customer, Payment payment);

I want to query all orders based on customerId and paymentId. Both the objects are neccessry in the above query. But spring-data-rest returns null if I gave cutomerId doesn't exists in database. I expect spring-data-rest to throw exception if object doesn't exists in database.

How to achieve this?

like image 815
SST Avatar asked Oct 04 '16 10:10

SST


3 Answers

You just need orElseThrow

orderRepository.findByCustomerAndPayment(customer, payment).orElseThrow(() -> new ResourceNotFoundException("customer", "id", customer.getId()));
like image 154
Salah Atwa Avatar answered Oct 09 '22 09:10

Salah Atwa


If you're using Java 8, you can use Optional<Order> as the return type of the repository method. If the repository method returns an empty Optional calling get on it will throw a NoSuchElementException. Otherwise there is no support for throwing exceptions by repository methods if there are no results.

try {
  Optional<Order> result = repository.findByCustomerAndPayment(customer,payment);
  Order order = result.get();
} catch(NoSuchElementException e) {
  // do something with the exception
}
like image 27
Strelok Avatar answered Oct 09 '22 07:10

Strelok


You can make custom repository implementation like below:

public interface OrderRepositoryCustom {
    Order findByCustomerAndPaymentRequired(Customer customer, Payment payment);
}

public class OrderRepositoryImpl implements OrderRepositoryCustom {

    @Autowired 
    OrderRepository orderRepository;

    @Override
    public Order findByCustomerAndPaymentRequired(Customer customer, Payment payment) {
        Order o = orderRepository.findByCustomerAndPayment(customer, payment);
        if(o == null) {
            throw new IncorrectResultSizeDataAccessException(1);
        }
        return o;
    }

}

Your OrderRepository interface should extend customized:

public interface OrderRepository extends CrudRepository<Order, Long>, OrderRepositoryCustom {
    Order findByCustomerAndPayment(Customer customer, Payment payment);
}

Edited

As IncorrectResultSizeDataAccessException is RuntimeException, then no need to throws declaration - i fixed that.

like image 4
marioosh Avatar answered Oct 09 '22 09:10

marioosh