Spring Boot后控制器无法找到数据库ID,返回可选错误[关闭]

Posted

技术标签:

【中文标题】Spring Boot后控制器无法找到数据库ID,返回可选错误[关闭]【英文标题】:SpringBoot post controller unable to find DB id, returning Optional Error [closed] 【发布时间】:2021-05-28 06:17:30 【问题描述】:

你好朋友我正在使用 Thymeleaf 创建一个图书馆管理应用程序,我已经映射了关系并创建了一些关系,并且多对多的关系正在工作,例如你将注册一本书(只有名称),然后它将有一个名为 details 的链接,您可以在其中完成注册并选择作者和主题,两者都是多对多关系及其工作

Book Register Details 显示一本已创建的图书

现在我的问题在于多对一关系,它的工作方式相同,您将创建一个图书馆,然后在详细信息中您将能够将书籍添加到该图书馆

在我正在创建的项目中,一个图书馆可以有多本书,但一本书只能在一个图书馆中,这是该图书馆独有的,当我尝试添加该书并提交时,我收到一条错误消息:

不存在价值 java.util.NoSuchElementException:不存在值 在 java.base/java.util.Optional.get(Optional.java:141)

我试图解决这个问题几个小时,我的猜测是控制器无法找到 Book id,但我不知道为什么......

这是我上面的代码: Ps:我知道我有工作要做,创建 DTO 并使其更清洁,我只想让它先工作

Library COntroller 是我试图在 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 方法.get 它来自一个可选接口,它检查它是否有值,但是 id 在我的数据库上,他只是无法找到 id,我尝试制作书控制器上的关系并且它有效,但在图书馆控制器中它没有。

【问题讨论】:

【参考方案1】:

您必须使用 @JoinColumn(name = "column_name_who_points_to_LibraryID") 注释来注释图书实体的库对象。并且还在您的库实体中包含 mappedBy 属性。 图书实体

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 
    
    // Book constructor and other code
    @ManyToOne
    @JoinColumn(name = "library_id") // here library_id is a foreign key in Book table
    private Library library;

图书馆实体

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 
    // Library Constructor and other code
    @OneToMany(mappedBy = "library") // this is a object name in Book Entity 
    private List<Book> book = new ArrayList<>();

【讨论】:

谢谢朋友!!!

以上是关于Spring Boot后控制器无法找到数据库ID,返回可选错误[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot WebSockets 无法找到当前用户(主体)

Spring-boot,无法自动装配类。未找到默认构造函数引发异常

Spring Boot Web 应用程序给出 500 内部服务器错误,而不是 404 未找到

Spring Boot:无法登录 h2 控制台

如何在spring boot和hibernate中计算特定id的记录

Spring Boot配置Mysql后无法根据java实体类生成table