Spring Data JPA findOne() change to Optional how to use this?

前端 未结 5 1182
一生所求
一生所求 2020-12-12 10:26

I\'m learning SpringBoot2.0 with Java8.

And I followed some blog-making tutorial example.

The tutorial source code is:



        
5条回答
  •  一生所求
    2020-12-12 11:18

    From at least, the 2.0 version, Spring-Data-Jpa modified findOne().
    Now, findOne() has neither the same signature nor the same behavior.
    Previously, it was defined in the CrudRepository interface as:

    T findOne(ID primaryKey);
    

    Now, the single findOne() method that you will find in CrudRepository is the one defined in the QueryByExampleExecutor interface as:

     Optional findOne(Example example);
    

    That is implemented finally by SimpleJpaRepository, the default implementation of the CrudRepository interface.
    This method is a query by example search and you don't want that as a replacement.

    In fact, the method with the same behavior is still there in the new API, but the method name has changed.
    It was renamed from findOne() to findById() in the CrudRepository interface :

    Optional findById(ID id); 
    

    Now it returns an Optional, which is not so bad to prevent NullPointerException.

    So, the actual method to invoke is now Optional findById(ID id).

    How to use that?
    Learning Optional usage. Here's important information about its specification:

    A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.

    Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present).


    Some hints on how to use Optional with Optional findById(ID id).

    Generally, as you look for an entity by id, you want to return it or make a particular processing if that is not retrieved.

    Here are three classical usage examples.

    1. Suppose that if the entity is found you want to get it otherwise you want to get a default value.

    You could write :

    Foo foo = repository.findById(id)
                        .orElse(new Foo());
    

    or get a null default value if it makes sense (same behavior as before the API change) :

    Foo foo = repository.findById(id)
                        .orElse(null);
    
    1. Suppose that if the entity is found you want to return it, else you want to throw an exception.

    You could write :

    return repository.findById(id)
            .orElseThrow(() -> new EntityNotFoundException(id));
    
    1. Suppose you want to apply a different processing according to if the entity is found or not (without necessarily throwing an exception).

    You could write :

    Optional fooOptional = fooRepository.findById(id);
    if (fooOptional.isPresent()) {
        Foo foo = fooOptional.get();
        // processing with foo ...
    } else {
        // alternative processing....
    }
    

提交回复
热议问题