java - Spring Boot findbyid 返回可选错误
问题描述
你好朋友我正在用 Thymeleaf 创建一个图书馆管理应用程序,我已经映射了关系并创建了一些关系,并且多对多的关系正在工作,例如你将注册一本书(只有名称),然后它将有一个链接命名详细信息,您将能够在其中完成注册并选择作者和主题,两者都是多对多关系及其工作
现在我的问题是多对一关系,它的工作方式相同,您将创建一个图书馆,然后在详细信息中您将能够将书籍添加到该图书馆
在我正在创建的项目中,一个图书馆可以有多本书,但一本书只能在一个图书馆中,这是该图书馆独有的,当我尝试添加这本书并提交时,我收到一条错误消息:
不存在值 java.util.NoSuchElementException:java.base/java.util.Optional.get 中不存在值(Optional.java:141)
我试图解决这个问题几个小时,我的猜测是控制器无法找到 Book id,但我不知道为什么......
这是我上面的代码: Ps:我知道我有工作要做,创建 DTO 并使其更清洁,我只想让它先工作
这里的图书馆控制器是我试图在 ediLib 方法中添加创建的书的地方
package com.msoftwares.librarymanager.controller;
import com.msoftwares.librarymanager.models.Entities.Book;
import com.msoftwares.librarymanager.models.Entities.Library;
import com.msoftwares.librarymanager.models.Repo.LibraryRepository;
import com.msoftwares.librarymanager.models.Services.BookService;
import com.msoftwares.librarymanager.models.Services.LibraryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import java.util.List;
@RestController
@RequestMapping(path ="/api/library")
public class LibraryController {
@Autowired
LibraryService libraryService;
@Autowired
BookService bookService;
@GetMapping(path = "/all")
public ModelAndView getLibraries(){
ModelAndView modelAndView = new ModelAndView("libraryTemplate");
modelAndView.addObject("newLibrary", new Library());
modelAndView.addObject("getLibraries", libraryService.getLibrary());
return modelAndView;
}
@GetMapping(path = "/details/{id}")
public ModelAndView getDetails(@PathVariable("id") Integer id){
Library library = libraryService.findLibById(id);
ModelAndView modelAndView = new ModelAndView("libraryEdit");
modelAndView.addObject("library", library );
List<Book> unselectedBooks = bookService.getBooks();
unselectedBooks.removeAll(library.getBook());
modelAndView.addObject("availableBooks", unselectedBooks);
return modelAndView;
}
@PostMapping(path = "/editLib")
public RedirectView editLib(@ModelAttribute Book book, @RequestParam Integer libId){
Library library = libraryService.findLibById(libId);
book = bookService.getBookById(book.getIsbn());
libraryService.saveLibrary(library);
return new RedirectView("http://localhost:8080/api/library/details/" + libId);
}
@PostMapping(path = "/create")
public RedirectView createLibrary(@ModelAttribute Library library){
libraryService.saveLibrary(library);
return new RedirectView("http://localhost:8080/api/library/all");
}
}
图书控制器
package com.msoftwares.librarymanager.controller;
import com.msoftwares.librarymanager.models.Entities.Author;
import com.msoftwares.librarymanager.models.Entities.Book;
import com.msoftwares.librarymanager.models.Entities.BookTheme;
import com.msoftwares.librarymanager.models.Entities.Library;
import com.msoftwares.librarymanager.models.Repo.AuthorRepository;
import com.msoftwares.librarymanager.models.Repo.BookRepository;
import com.msoftwares.librarymanager.models.Repo.BookThemeRepository;
import com.msoftwares.librarymanager.models.Repo.LibraryRepository;
import com.msoftwares.librarymanager.models.Services.AuthorService;
import com.msoftwares.librarymanager.models.Services.BookService;
import com.msoftwares.librarymanager.models.Services.BookThemeService;
import com.msoftwares.librarymanager.models.Services.LibraryService;
import org.dom4j.rule.Mode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import javax.swing.text.html.HTML;
import java.util.List;
@RestController
@RequestMapping(path ="/api/books")
public class BookController {
@Autowired
BookService bookService;
@Autowired
AuthorService authorService;
@Autowired
BookThemeService bookThemeService;
//get all books
@GetMapping(path = "/all")
public ModelAndView getBooks(){
ModelAndView modelAndView = new ModelAndView("booksTemplate");
modelAndView.addObject("newBook", new Book());
modelAndView.addObject("getAuthors", authorService.getAuthors());
modelAndView.addObject("getBooks", bookService.getBooks());
modelAndView.addObject("getThemes", bookThemeService.getThemes());
return modelAndView;
}
//create book
@PostMapping(path = "/create")
public RedirectView createBook(@ModelAttribute Book book) {
bookService.saveBook(book);
return new RedirectView("http://localhost:8080/api/books/all");
}
//get details
@GetMapping(path = "/details/{id}")
public ModelAndView getDetails(@PathVariable("id") Integer id){
Book book = bookService.getBookById(id);
ModelAndView modelAndView = new ModelAndView("bookDetails");
modelAndView.addObject("bookId", book);
List<Author> unselectedAuthors = authorService.getAuthors();
List<BookTheme> unselectedBookThemes = bookThemeService.getThemes();
unselectedAuthors.removeAll(book.getAuthors());
unselectedBookThemes.removeAll(book.getBookThemes());
modelAndView.addObject("authors", unselectedAuthors);
modelAndView.addObject("bookThemes", unselectedBookThemes);
return modelAndView;
}
//register authors
@PostMapping(path = "/registerDetails")
public RedirectView registerDetails(@ModelAttribute Author author, @RequestParam Integer isbn){
Book book = bookService.getBookById(isbn);
author = authorService.getAuthorById(author.getId());
book.getAuthors().add(author);
bookService.saveBook(book);
return new RedirectView("http://localhost:8080/api/books/details/" + isbn);
}
//register themes
@PostMapping(path = "/registerTheme")
public RedirectView registerThemes(@ModelAttribute BookTheme bookTheme, @RequestParam Integer isbn){
Book book = bookService.getBookById(isbn);
bookTheme = bookThemeService.getThemeById(bookTheme.getId());
book.getBookThemes().add(bookTheme);
bookService.saveBook(book);
return new RedirectView("http://localhost:8080/api/books/details/" + isbn);
}
}
图书馆服务
package com.msoftwares.librarymanager.models.Services;
import com.msoftwares.librarymanager.models.Entities.Book;
import com.msoftwares.librarymanager.models.Entities.Library;
import com.msoftwares.librarymanager.models.Repo.LibraryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class LibraryService {
@Autowired
LibraryRepository libraryRepository;
@Autowired
BookService bookService;
//get all
public List<Library> getLibrary(){return libraryRepository.findAll();}
//get by id
public Library findLibById(int id){return libraryRepository.findById(id).get();}
//save
public void saveLibrary(Library library){libraryRepository.save(library);}
//delete
public void deleteLibrary(Library library){libraryRepository.delete(library);}
}
图书服务(finById 方法所在的位置)
package com.msoftwares.librarymanager.models.Services;
import com.msoftwares.librarymanager.models.Entities.Author;
import com.msoftwares.librarymanager.models.Entities.Book;
import com.msoftwares.librarymanager.models.Repo.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class BookService {
@Autowired
BookRepository bookRepository;
//get all books
public List<Book> getBooks(){
return bookRepository.findAll();
}
//save book
public void saveBook(Book book){
bookRepository.save(book);
}
//find books by id
public Book getBookById(int id){
return bookRepository.findById(id).get();
}
//delete
public void deleteBook(Book book){
bookRepository.delete(book);
}
}
图书馆实体
package com.msoftwares.librarymanager.models.Entities;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Library {
public Library(String name, String address) {
this.name = name;
this.address = address;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int id;
@Column
private String name;
@Column
private String address;
@ManyToMany(fetch = FetchType.LAZY)
private List<Client> clients = new ArrayList<>();
@OneToMany
private List<Book> book = new ArrayList<>();
}
图书实体
package com.msoftwares.librarymanager.models.Entities;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class Book {
public Book(String title) {
this.title = title;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int isbn;
@Column
private String title;
@ManyToMany(fetch = FetchType.LAZY)
private List<Author> authors = new ArrayList<>();
@ManyToMany(fetch = FetchType.LAZY)
private List<BookTheme> bookThemes = new ArrayList<>();
@ManyToOne
private Library library;
}
我看到 findById 方法。它来自一个可选接口,它检查它是否有值,但是 id 在我的数据库中,他只是无法找到 id,我尝试在 Book 上建立关系控制器,它工作,但在图书馆控制器它没有。
解决方案
检查您的代码后,您的问题出在您的 thymeleaf 模板中。
库编辑.html
<form th:action="@{/api/library/editLib/(libId=${library.id})}" method="post">
<label><b> Select Books</b></label>
<select name="id" required>
<option value="">Choose books</option>
<option th:each="book : ${availableBooks}"
th:value="${book.isbn}"
th:text="${book.title}">
</option>
</select>
<input type="submit" value="Save" />
</form>
您必须使用isbn更改id
<select name="isbn" required>
因为您的实体 Book的 ID 为isbn :
public class Book {
//...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int isbn;
// ...
您对此感到困惑,因为例如 bookDetails.html,您可以毫无问题地使用“id”作为作者和主题,因为
<select name="id" required>
他们的实体同时拥有
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private int id;
要了解有关 ModelAttribute 如何工作的更多信息,请参阅此链接,
推荐阅读
- node.js - MongoDB:findOne返回null但集合中存在子文档
- python - Tensorflow/Keras 似乎改变了我的批量大小
- python - 如何过滤两个模型之间的差异?使用 django
- cypress - Percy - Cypress - 错误:找不到浏览器修订版 756035。运行“npm install”或“yarn install”下载浏览器二进制文件
- apache-kafka - Kafka Connect - JDBC Avro 连接如何定义自定义模式注册表
- reactjs - 我们不能直接将组件注入 App.js 吗?
- javascript - 如何让JS更随机?
- javascript - JS按钮点击提示从文本到下拉菜单
- colors - 为什么 HSV 到 BGR 和 BGR 到 HSV 的转换不匹配?
- prolog - SWI-Prolog 编辑器接受无效编码