Search code examples
springspring-data-jpacrudjpql

Does it auto construct queries


My end to end flow is as given below: controller -> adapter -> persistence/repository -> DB

In my controller:

@RequestMapping(value = "/userOrder/{orderID}", method = RequestMethod.DELETE)
   public Set<?> deleteOrder(@PathVariable("orderID") String orderID) {
   /*
    * orderHandlerAdapter cancels the order and passed list of orders created + cancelled so  * far.
    */
    Set<Orders> orderList = orderHandlerAdapter.cancelOrder(orderID);
    return orderList;
   }

In adapter:

public Set<Order> cancelOrder(String orderID) {
/*
 * Cancel order first.
 */
    userOrderRepository.saveOrder(orderID,"CANCELLED");
/*
 * Return list of orders created and cancelled so far.
 */
    Set<Order> orderList = userOrderRepository.getFirstByOrderIdAndStatusCdIsIn(orderID, new Set<String> {"CREATED","CANCELLED"});
    return Set<Order>;
}

In persistence:

    public interface orderRespository extends CrudRepository<UserOrder,String>() {
/*
 * Save status = CANCELLED into the DB.
 */
    void saveOrder(String orderID);
    /*
     * Get orders that are created and cancelled.
     */
    Set<Order> getFirstByOrderIdAndStatusCdIsIn(String orderID, new Set<String> orderStatusSet); 
    }

I find that when saveOrder/getFirstByOrderIdAndStatusCdIsInis called, the queries are not defined anywhere, and the interface is not implemented either. But the result is returned correctly.

How does this work? Is JPA intelligent enough to create queries based on the method names?


Solution

  • Spring Data has a default implementation for the methods from the repositories included in the product (CrudRepository, PagingAndSortingRepository, JpaRepository, QueryByExampleExecutor). You can find many in the SimpleJpaRepository.

    But it is not just that an instance of SimpleJpaRepository gets added to the ApplicationContext. instead, a proxy is used. The proxy checks the method being called and decides how to provide an implementation:

    1. Is it a predefined method -> call its implementation
    2. Does it have a @Query annotation or does its name match a named query -> call that
    3. Can its name converted into a query -> do so.

    Beyond that Spring Data takes care of conversions between results of the queries and the required return type of the method.