https://www.youtube.com/watch?v = jcyonzey5dy&t =1145S

问题描述 投票:0回答:1

书课: @Table(name = "Books") @Entity @Setter @Getter @AllArgsConstructor @NoArgsConstructor public class Book { @Id @SequenceGenerator( name = "book_sequence", sequenceName = "book_sequence", allocationSize = 1 ) @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "book_sequence" ) private Long bookId; private String title; private LocalDate releaseDate; private String genresStr; @Column(columnDefinition = "text") private String content; @ManyToMany(mappedBy="books", fetch=FetchType.LAZY, cascade = CascadeType.ALL) private Set<Users> authors; public Book(String title, LocalDate releaseDate, String content, String genresStr){ this.genresStr = genresStr; this.title= title; this.releaseDate = releaseDate; this.content = content; } public Book(String title, LocalDate releaseDate, String content, String genresStr, Set<Users> authors){ this.genresStr = genresStr; this.title= title; this.releaseDate = releaseDate; this.content = content; this.authors = authors; } public void addAuthors(Set<Users> authors){ System.out.println("addAuthorsCalled"); for(Users author : authors) try{ this.authors.add(author); author.addBooks(Set.of(this)); author.setRole(Roles.AUTHOR); } catch(Exception e){ System.out.println("Wrong type of object for a List of Users"); } } public void removeAuthors(Set<Users> authors){ if(authors.size() == 1){ System.out.println("Can't delete all authors for certain book"); return; } for(Users author : authors) for(Users user : this.authors){ if (user.equals(author)) { this.authors.remove(user); } else{ System.out.println("User: "+author.getFullName()+ " is already not in set."); } } } }

书控制器:

@RestController
@RequestMapping(path = "api/books")
public class BookController {
    
    private final BookService bookService;
    private UserService userService;


    public BookController(@Autowired BookService bookService, UserService userService){
        this.bookService = bookService;
        this.userService = userService;
    }


    @GetMapping
    public List<Book> getBooks(){
        return bookService.getBooks();
    }

    @PostMapping
    public void addBook(@RequestBody Book book){
        if(!book.getAuthors().isEmpty()){
            for(Users author :  book.getAuthors()){
                author.setRole(Roles.AUTHOR);
                userService.saveUser(author);
            }
        }
        bookService.saveBook(book);
    }

    @DeleteMapping(path="{bookId}")
    public void deleteBook(@PathVariable ("bookId") Long bookId){
        bookService.deleteBook(bookId);
    }

    @PutMapping(path="{bookId}")
    public void updateBook(
        @PathVariable("bookId") Long bookId,
        @RequestParam(required = false) String title,
        @RequestParam(required = false) LocalDate releaseDate, 
        @RequestParam(required = false) String content,
        @RequestParam(required = false) Set<Long> userIds

    ){
        Set<Users> usersToAdd = null;
        if(userIds!=null){
            usersToAdd = userService.getUsersById(userIds);
        }
        bookService.updateBook(bookId, title, releaseDate, content, usersToAdd);
    }

    @PutMapping(path = "/{bookId}/delAuthor")
    public void putMethodName(
        @PathVariable Long bookId,
        @RequestParam(required = true) Set<Long> userIds
    ){
        Set<Users> usersToRemove = userService.getUsersById(userIds);
        bookService.removeAuthors(bookId, usersToRemove);

    }
}

用户控制器:

@RestController
@RequestMapping(path = "api/users")
public class UserController {
    
    private final UserService userService;

    public UserController(@Autowired UserService userService){
        this.userService = userService;
    }

    @GetMapping
    public List<Users> getAllUsers() {
        return userService.getUsers();
    }

    @PostMapping
    public void addNewUser(@RequestBody Users user) {
        userService.saveUser(user);
        
    }

    @DeleteMapping(path="{userId}")
    void deleteUser(@PathVariable ("userId") Long userId){
        userService.deleteUser(userId);
    }

    @PutMapping(path="{userId}")
    void updateUser(@PathVariable ("userId") Long userId,
        @RequestParam(required = false) String fullName,
        @RequestParam(required = false) String password,
        @RequestParam(required = false) LocalDate dateOfBirth,
        @RequestParam(required = false) String email,
        @RequestParam(required = false) Set<Long> bookIds
    ){
        userService.updateUser(userId, password, dateOfBirth, fullName, email, bookIds);
    }
}

用户服务

@Service
public class UserService {

    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    private final UserRepository userRepository;
    private BookRepository bookRepository;

    public UserService(@Autowired UserRepository userRepository, BookRepository bookRepository){
        this.userRepository = userRepository;
        this.bookRepository = bookRepository;
    }

    public Users getUser(Long id){
        return this.userRepository.getReferenceById(id);
    }

    public List<Users> getUsers(){
        return this.userRepository.findAll();
    }

    public Set<Users> getUsersById(Set<Long> userIds){
        Set<Users> users = new HashSet<>();
        for(Long userId : userIds)
            if(userId != null){
                users.add(this.getUser(userId));
            }
        return users;
    }

    public void saveUser(Users user){
        Optional<Users> userEmailOptional = userRepository.findUserByEmail(user.getEmail());
        if(userEmailOptional.isPresent()){
            throw new IllegalStateException("This email already exists in database");
        }

        if(user.getRole() == Roles.AUTHOR){
            Optional<Users> authorByFullName = userRepository.findUserByFullName(user.getFullName());
            if(authorByFullName.isPresent()){
                throw new IllegalStateException("Authors cannot have the same name");
            }
        }
        if(user.getBooks() != null && !user.getBooks().isEmpty())
            user.setRole(Roles.AUTHOR);

        user.setPassword(encoder.encode(user.getPassword()));
        if(user.getBooks() != null && !user.getBooks().isEmpty())
            for(Book book : user.getBooks())
                bookRepository.save(book);
        userRepository.save(user);
    }

    public void deleteUser(Long userId){
        boolean exists = userRepository.existsById(userId);
        if(!exists){
            throw new IllegalStateException("No user with Id: " + userId+ " in database");
        }
        userRepository.deleteById(userId);
    }

    @Transactional
    public void updateUser(Long userId,
                            String password,
                            LocalDate dateOfBirth,
                            String fullName,
                            String email,
                            Set<Long> bookIds){
        Users user = userRepository.findById(userId).orElseThrow(() -> 
                    new IllegalStateException("No user with id: "+userId+" in database"));
        if(password != null && password.length() > 0){
            user.setPassword(password);
        }
        if(dateOfBirth!=null){
            user.setDateOfBirth(dateOfBirth);
        }
        if(fullName!=null && fullName.length() > 0){
            user.setFullName(fullName);
        }
        if(email!=null && email.length() > 0){
            Optional<Users> userOptional = userRepository.findUserByEmail(email);
            if(userOptional.isPresent()){
                throw new IllegalStateException("Email "+email+" already exists in database");
            }
            user.setEmail(email);
        }
        if(bookIds != null){
            Set<Book> booksToAdd = new HashSet<Book>();
            for(Long bookId : bookIds){
                booksToAdd.add(bookRepository.getReferenceById(bookId));
            }
            user.addBooks(booksToAdd);
        }
    }
}

书服务:

@Service
public class BookService {
    
    private final BookRepository bookRepository;

    public BookService(@Autowired BookRepository bookRepository){
        this.bookRepository = bookRepository;
    }

    public List<Book> getBooks(){
        return bookRepository.findAll();
        //List.of(new Book("kostas", LocalDate.of(2000, Month.APRIL, 12)));
    }

    public void saveBook(Book book){
        
        bookRepository.save(book);
    }

    public void deleteBook(Long bookId){
        boolean exists = bookRepository.existsById(bookId);
        if(!exists){
            throw new IllegalStateException("Book with id: " + bookId + " does not exist");
        }
        bookRepository.deleteById(bookId);
    }

    @Transactional
    public void removeAuthors(Long bookId, Set<Users> authors){
        Book book = bookRepository.findById(bookId).
            orElseThrow(() -> new IllegalStateException("No books with the id requested"));
        if(!authors.isEmpty())
            book.removeAuthors(authors);
    }

    @Transactional
    public void updateBook(Long bookId, String title, LocalDate releasDate, String content, Set<Users> authors){
        Book book = bookRepository.findById(bookId).
            orElseThrow(() -> new IllegalStateException("No books with the id requested"));
        
        if(title != null && title.length() > 0){
            book.setTitle(title);
        }
        if(releasDate != null){
            book.setReleaseDate(releasDate);
        }
        if(content != null && content.length() > 0){
            book.setContent(content);
        }
        if(authors != null)
            book.addAuthors(authors); 
    }
}

形是一个简单的枚举:

public enum Roles {
    AUTHOR, ADMIN, GUEST
}
postman请求的示例:

post:localhost:8080/api/用户

//用书插入用户 //正常工作
body:
{
    "password":"itsDanBrown",
    "dateOfBirth":"1964-07-22",
    "fullName":"Dan Brown",
    "email":"[email protected]",
    "books":[
        {
            "title":"The Da Vinci Code",
            "releaseDate":"2003-03-18",
            "content":"",
            "genres":["Mystery", "detective fiction", "conspiracy fiction", "thriller"]
        },
        {
            "title":"Angels & Demons",
            "releaseDate":"2000-05-30",
            "content":"",
            "genres":["Mystery", "thriller"]
        }
    ]
}

post:localhost:8080/api/用户

//与用户插入书 //在用户表和书籍表中插入值,但在用户_Books表
{
    "title":"The Da Vinci Code",
    "releaseDate":"2003-03-18",
    "content":"",
    "genres":["Mystery", "detective fiction", "conspiracy fiction", "thriller"],
    "authors":[
        {
        "password":"password",
        "dateOfBirth":"2000-02-02",
        "fullName":"Dan Brown",
        "email": "[email protected]"
        }
    ]
}

提前感谢! (Java版本18,Spring Boot 3.4.2)


在那里!


在春季JPA @manytomany关系中,一侧被指定为关系的所有者。所有者方负责管理联盟表中的实体之间的链接。
在您的病例中发生了什么

在您的示例中,用户是关系的自然方面。 当您致电 /用户端点时: 用户服务单独保存(从请求)。 然后,它保存了用户 - 与所有书籍相关联。 此序列允许Hibernate在users_books Join表中创建链接。 aissue with /books端点

java postgresql spring-boot jpa many-to-many
1个回答
0
投票
当您致电 /书籍端点时: 您可以从请求中检索作者(用户)。 您将其角色设置并保存在数据库中。 但是,没有创建该链接,因为自有方(用户)没有对本书的引用。没有此参考,Hibernate不知道它应该在

USERS_BOOKS加入表中创建一个条目。

如何修复

if (!book.getAuthors().isEmpty()) { for (Users author : book.getAuthors()) { author.setRole(Roles.AUTHOR); author.addBooks(Set.of(book)); // Establish the bidirectional link userService.saveUser(author); } } bookService.saveBook(book);

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.