Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CrudRepository findById dont return java.util. Optional

public interface LmsRepository extends CrudRepository I have no findOne method for getting single count so when i using findById I got this exception."Property [id] not found on type [java.util.Optional]" How can i solve this trouble ?

This is my CrudRepo

@Repository
public interface LmsRepository extends CrudRepository<Book, Long> {


}

Entity File

@Entity(name="lms_tbl")
public class Book {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Column(name="book_name")
private String bookName;

private String author;

@Column(name="purchase_date")
@Temporal(TemporalType.DATE)
private Date purchaseDate;

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

and other....

Service File

@Service
public class LmsService {

@Autowired
private LmsRepository lmsRepository;

public Collection<Book> findAllBooks(){
    ArrayList<Book> books = new ArrayList<Book>();
    for (Book book : lmsRepository.findAll()) {
        books.add(book);
    }

    return books;
}

public void deleteBook(long id) {

    lmsRepository.deleteById(id);
}

public Optional<Book> findById(Long id) {

    return lmsRepository.findById(id);
}

}

Controller File

@Controller
public class MainController {

@Autowired
private LmsService lmsService;


@GetMapping("/")
public String index(HttpServletRequest req) {
    req.setAttribute("books", lmsService.findAllBooks());
    req.setAttribute("mode","BOOK_VIEW");
    return "index";
}

@GetMapping("/updateBook")
public String index(@RequestParam Long id,HttpServletRequest req) {
    req.setAttribute("book", lmsService.findById(id));
    req.setAttribute("mode","BOOK_EDIT");
    return "index";
}

}

I tried add new method in CrudRepo but it doesnt work.

like image 584
Zülküf ADSIZ Avatar asked Jan 02 '23 00:01

Zülküf ADSIZ


1 Answers

In your service class change this

public Optional<Book> findById(Long id) {
    return lmsRepository.findById(id);
}

to this

public Book findById(Long id) {
    return lmsRepository.findById(id).get();
}

Explanation: Optional is a wrapper class which may or may not contain a non-null value. You get that error because you are trying to insert Optional in the model, not Book. As Optional does not contain any id field, you get the error. Optional is used for having defalut values of throwing exception when you have a null object where you do not expect it to be null. You can create for example an automatic exception throwing in case of null optional. For example, you can upgrade your service in this way:

public Book findById(Long id) {
    return lmsRepository.findById(id).orElseThrow(RuntimeException::new);
}

This will throw a RuntimeException any time Book is null inside the Optional, or will give you back the value of the Book class.

A more elegant solution is the following:

public Book findById(Long id) {
    return lmsRepository.findById(id).orElseThrow(NotFoundException::new);
}

having:

@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{
}

In this way when the optional contains a Book, that is returned back to the controller and inserted in model. If the Optional contains a null value then NotFoundException will be thrown, it does not need to be catched, and will be mappet to 404 HTTP error.

like image 185
Lorelorelore Avatar answered Jan 04 '23 15:01

Lorelorelore