beginner here. I don't know how to show books and their authors in one list on the page. My first project was simplified and looked like this:
Book.java
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "author")
**private String author;**
@Column(name = "title")
private String title;
@Column(name = "isbn")
private String isbn;
public Book() {
}
public Book(String author, String title, String isbn) {
this.author = author;
this.title = title;
this.isbn = isbn;
}
(...)
}
IndexController.java
@Controller
public class IndexController {
private BookService bookService;
@Autowired
public IndexController(BookService bookService) {
this.bookService = bookService;
}
@RequestMapping({"/", "", "/index"})
public String showAll(Model model) {
model.addAttribute("books", bookService.getAllBooks());
return "index";
}
}
index.html (thymeleaf)
<table>
<thead>
<tr>
<th> Number</th>
<th> Author</th>
<th> Title</th>
<th> ISBN</th>
</tr>
</thead>
<tbody>
<tr th:if="${books.isEmpty()}">
<td colspan="3"> No records</td>
</tr>
<tr th:each="book, stat : ${books}" th:object="${book}">
<!-- added for numbering purpose, variable stat is needed for iteration -->
<td th:text="${stat.count}">1</td>
<td th:text="*{author}"> Author</td>
<td th:text="*{title}"> Title</td>
<td th:text="*{isbn}"> ISBN</td>
</tr>
</tbody>
</table>
It was fine, data was working in my index.html list of books that way. But the problem is that a book might have many authors and many authors many books so I had to improve my model to look like that:
Book.java
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String isbn;
@ManyToMany
@JsonIgnore // removed wierd loop with data
@JoinTable(name = "author_book", joinColumns = @JoinColumn(name = "book_id"),
inverseJoinColumns = @JoinColumn(name = "author_id"))
**private Set<Author> authors = new HashSet<>();**
public Book() {
}
public Book(String title, String isbn) {
this.title = title;
this.isbn = isbn;
}
public Book(String title, String isbn, Set<Author> authors) {
this.title = title;
this.isbn = isbn;
this.authors = authors;
}
(...)
}
And had to create new Author.java entity:
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String forename;
private String surname;
@ManyToMany(mappedBy = "authors")
private Set<Book> books = new HashSet<>();
public Author() {
}
public Author(String forename, String surname) {
this.forename = forename;
this.surname = surname;
}
public Author(String forename, String surname, Set<Book> books) {
this.forename = forename;
this.surname = surname;
this.books = books;
}
(...)
}
Could you please instruct me what should I do now? I want to show a list of books with authors in thymeleaf
but I don't know how to create it in index.html so it would show all data. Do I have to change my IndexController (showAll() method)
? Any advice would be greatly appreciated.
EDIT after Istiaque Hossain's post:
Now it is working but code does not look good (those 2 spans), advices how to make it better appreciated.
index.html
<table>
<thead>
<tr>
<!-- th Number added for numbering purpose-->
<th> Number</th>
<th> Author_Name</th>
<th> Author_Surn</th>
<th> Title</th>
<th> ISBN</th>
</tr>
</thead>
<tbody>
<tr th:if="${books.isEmpty()}">
<td colspan="3"> No records</td>
</tr>
<tr th:each="book, stat : ${books}" th:object="${book}">
<!-- added for numbering purpose, variable stat is needed for iteration -->
<td th:text="${stat.count}">1</td>
<td>
<span th:each="author : ${book.authors}">
<span th:utext="${author.forename}" />
</span>
</td>
<td>
<span th:each="author : ${book.authors}">
<span th:utext="${author.surname}" />
</span>
</td>
<td th:text="*{title}"> Title</td>
<td th:text="*{isbn}"> ISBN</td>
</tr>
</tbody>
</table>
Looks like that: enter image description here