Reputation: 507
Im trying to put the RoomEntity Class in the List as its generic parameter but the List Class turns red(Error) and the only thing that it suggests is for me to change the List Class to Optional Class.
public interface RoomRepository extends CrudRepository<RoomEntity, Long> {
List<RoomEntity> findById(Long id);
}
RoomEntity Class
@Entity
@Table(name = "Room")
public class RoomEntity {
}
are they the same?
List<RoomEntity> findById(Long id);
Optional<RoomEntity> findById(Long id);
Upvotes: 1
Views: 8687
Reputation: 398
Optional and List are two very different concepts.
The CrudRepository findAllById method returns an Iterable. The findById method returns an Optional.
An iterable can be used to access one by one the elements of a collection and so can be used in conjunction with the List class.
An Optional is a container object which may or may not contain a non-null value (zero or one elements). This will have a single element in it, not many elements like in a List, if there is one.
The CrudRepository::findAllById can have more than one ID sent to it and so can return more than one element, the way it does this is to return an iterable you can use to select each of the returned results one by one. The findById method can only be sent a single ID and so returns that element if it is present (wrapped in an Optional), or an Optional.none if it is not.
If you are looking for a list to be returned because you intend to send in multiple IDs then use the findAllById method. If you want a specific element by ID only, then use the findById method but then you will have to unwrap the Optional object it is returned in before you can use it outside of a stream pipeline using Optional.get, Optional.isPresent, or using a map or flatmap call over it in a streams pipeline.
Upvotes: 2
Reputation: 18235
Spring data JPA will fit the query result to your desired container
You ask a List<>
, Spring will initialize a list and add any row data to that list and return it for you. Hence it will:
When you ask an Optional<>
, Spring will understand that you want at most one row data. It will interpreted as getSingleResult()
on javax.persistence.Query
. Hence it will:
Return Optional.empty()
if no items found
Return Optional.of(result)
if exactly one match
NonUniqueResultException
)In your case, you find by id
. It's unique on your table so Optional<>
should fit your purpose.
But note that your List<RoomEntity> findById(Long id);
definition is correct and it won't give you compiler error (turn red). Have you imported the List
interface?
Upvotes: 2
Reputation: 2216
Your findById
by definition should always return 1 or 0 entities(according to documentation for spring data method naming), as your id
is a unique key, and there cannot be more then one entry in your repository with such key value. So Optional
suits perfectly well for this situation, because its either empty
(no entry with such key in repository) or present
with specific value(there is entry in repository). If you want to query all entities by some not unique key, lets say name
column, you can name your method findByName
, with return value of Iterable<Entity>
, thus when generating implementation for your repository spring will understand that there can be more than 1 entity in result set.
Method findById
is already predefined in interface you are extending, so you couldn't change it return type anyway.
This also might be usefull: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.core-concepts
Upvotes: 0
Reputation: 81
The findById method is supposed to look for a single entity by it’s id. After all, ids are unique for every entity.
You can try to use findAllById
,
but I doubt it’ll make much difference.
What Optional means is that there may or may not be a result. The isPresent
method of Optional will indicate this.
Upvotes: 0