Cześć,
Potrzebuję wasze pomocy. Piszę właśnie aplikacje internetowej biblioteki za pomocą Spring Boot + thymeleaf. W związku z tym, że pomiędzy ksiażkami a autorami w bazie danych zachodzi relacja @Manytomany nie potrafię poradzić sobie z dodanie nowej ksiażki za pomocą formularza html. Czy ktoś mógłby mi podpowiedzieć jak to należy zrobić. Na dole wysyłam mój kod.
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "title")
private String title;
@Column(name = "year")
private Integer year;
@ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH})
@JoinTable(
name = "books_authors",
joinColumns = @JoinColumn(name = "book_id", unique = false),
inverseJoinColumns = @JoinColumn(name = "author_id", unique = false)
)
private List<Author> authors;
//konstruktory, gettery/settery toString()
}
import javax.persistence.*;
import java.util.List;
@Entity
@Table(name = "author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@ManyToMany(cascade = {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH})
@JoinTable(
name = "books_authors",
joinColumns = @JoinColumn(name = "author_id", unique = false),
inverseJoinColumns = @JoinColumn(name = "book_id", unique = false)
)
private List<Book> books;
//konstruktory gettery/settery toString()
}
import com.example.myTestProject.entity.Author;
import org.springframework.data.jpa.repository.JpaRepository;
public interface AuthorRepository extends JpaRepository<Author, Integer> {
}
import com.example.myTestProject.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Integer> {
}
mport com.example.myTestProject.entity.Book;
import java.util.List;
import java.util.Optional;
public interface BookService {
public List<Book> findAll();
public Optional<Book> findById(int theId);
public void save(Book theBook);
public void deleteById(int theId);
}
import com.example.myTestProject.dao.BookRepository;
import com.example.myTestProject.entity.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Service
public class BookServiceImpl implements BookService {
private BookRepository bookRepository;
@Autowired
public BookServiceImpl(BookRepository theBookRepository){
bookRepository = theBookRepository;
}
@Override
public List<Book> findAll() {
return bookRepository.findAll();
}
@Override
public Optional<Book> findById(int theId) {
Optional<Book> book = bookRepository.findById(theId);
if (book.isEmpty()){
throw new RuntimeException("Didn't find book id - " + theId);
}
else {
return book;
}
}
@Override
public void save(Book theBook) {
bookRepository.save(theBook);
}
@Override
public void deleteById(int theId) {
bookRepository.deleteById(theId);
}
}
import com.example.myTestProject.entity.Book;
import com.example.myTestProject.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("books")
public class BookController {
private BookService bookService;
@Autowired
public BookController(BookService theBookService){
bookService = theBookService;
}
@GetMapping("/list")
public String listBooks(Model theModel){
List<Book> theBooks = bookService.findAll();
//add to the spring model
theModel.addAttribute("books", theBooks);
return"books/list-books";
}
@GetMapping("/showFormForAdd")
public String showFormForAdd(Model theModel) {
// create model attribute to bind form data
Book theBook = new Book();
theModel.addAttribute("book", theBook);
return "books/book-form";
}
@PostMapping("/save")
public String saveBook(@ModelAttribute("book") Book theBook){
//save the book
bookService.save(theBook);
//use a ridirect to prevent duplicate submissions
return "redirect:/book/list";
}
}
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<title>Books</title>
</head>
<body>
<div class="container">
<h3>Books</h3>
<hr>
<!-- Add a button -->
<a th:href="@{/books/showFormForAdd}"
class="btn btn-primary btn-sm mb-3">
Add Book
</a>
<table class="table table-bordered table-striped">
<thead class="thead-dark">
<tr>
<th>Title</th>
<th>Year</th>
<th>Author</th>
</tr>
</thead>
<tbody>
<tr th:each="tempBook : ${books}">
<td th:text="${tempBook.title}" />
<td th:text="${tempBook.year}" />
<td th:text="${tempBook.authors}" />
</tr>
</tbody>
</table>
</div>
</body>
</html>
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<title>Save Book</title>
</head>
<body>
<div class="container">
<h3>Book Directory</h3>
<hr>
<p class="h4 mb-4">Save Book</p>
<form action="#" th:action="@{/books/save}"
th:object="${book}" method="post">
<input type="text" th:field="*{title}"
class="form-control mb-4 col-4" placeholder="Title">
<input type="text" th:field="*{year}"
class="form-control mb-4 col-4" placeholder="Year">
<input type="text" th:field="*{authors}"
class="form-control mb-4 col-4" placeholder="author">
<button type="submit" class="btn btn-info col-2">Save</button>
</form>
<hr>
<a th:href="@{/books/list}">Back to Employees List</a>
</div>
</body>
</html>
Z góry dziękuję za wszystkie podpowiedzi :)