Many to Many вывод данных Java

337
19 ноября 2017, 14:08

У меня есть БД с тремя таблицами User, Book и User_Book связующая для many to many. Делаю выборку связанных пользователей и книг.

Выборка книг:

 List<Book> listOrders = session.createQuery
   ("from BookManager.Model.Book as c inner join fetch c.usersOrder as j").list();

Выборка пользователей:

   List<User> listOrders = session.createQuery
   ("from BookManager.Model.User as c inner join fetch c.booksOrders as j").list();

Далее передаю в jsp

    model.addAttribute("listUsers", this.bookService.getUsersOrder());
    model.addAttribute("listBooks", this.userService.getBooksOrders());

В jsp таблица с тремя столбцами user.name, book.name, book.author.

Вопрос не могу понять как мне в таблице корректно отобразить эти данные. С списка достаю объекты

  <c:forEach items="${listUsers}" var="user" >
  <c:forEach items="${listBooks}" var="book" >

Может я изначально не правильно работаю с БД? Чую где-то туплю, но пока не пойму где именно.

Book:

@Entity
@Table(name = "books")
public class Book {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "BOOK_TITLE")
private String bookTitle;
@Column(name = "BOOK_AUTOR")
private String bookAutor;
@Column(name = "BOOK_PRICE")
private int price;

@Column(name = "BOOK_IMG")
@Lob
private Blob bookImg;
@Column(name = "BOOK_INFO")
private String bookInfo;
public Blob getBookImg()
{
    return bookImg;
}
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "books_users",
        joinColumns = { @JoinColumn(name = "book_id") },
        inverseJoinColumns = { @JoinColumn(name = "user_id") })
private Set<User> usersOrder = new HashSet<User>();
public void setBookImg(Blob bookImg) {
    this.bookImg = bookImg;
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getBookTitle() {
    return bookTitle;
}
public void setBookTitle(String bookTitle) {
    this.bookTitle = bookTitle;
}
public String getBookAutor() {
    return bookAutor;
}
public void setBookAutor(String bookAutor) {
    this.bookAutor = bookAutor;
}
public int getPrice() {
    return price;
}
public void setPrice(int price) {
    this.price = price;
}
public String getBookInfo() {
    return bookInfo;
}
public void setBookInfo(String bookInfo) {
    this.bookInfo = bookInfo;
}

public Set<User> getUsersOrder() {
    Hibernate.initialize(usersOrder);
    return usersOrder;
}
public void setUsersOrder(Set<User> UserOrders) {
    this.usersOrder = UserOrders;
}

public void addUser(User user)
{
    Hibernate.initialize(usersOrder);
    usersOrder.add(user);
}

User:

@Entity
@Table(name = "users")
public class User {
@Id
@Column
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column
private String username;
@Column
private String password;
@Column
private int access;
@Transient
private String passwordConfirm;

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "books_users",
        joinColumns = { @JoinColumn(name = "user_id") },
        inverseJoinColumns = { @JoinColumn(name = "book_id") })
private Set<Book> booksOrders = new HashSet<Book>();

public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getUsername() {
    return username;
}
public void setUsername(String username) {
    this.username = username;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}
public int getAccess() {
    return access;
}
public void setAccess(int access) {
    this.access = access;
}
public String getPasswordConfirm() {
    return passwordConfirm;
}
public void setPasswordConfirm(String passwordConfirm) {
    this.passwordConfirm = passwordConfirm;
}
public Set<Book> getBooksOrders() {
    Hibernate.initialize(booksOrders);
    return booksOrders;
}

Answer 1

Поскольку у вас всего 2 таблицы, и в пределах вашего вопроса предложу так:

Убрать ленивую загрузку книг у пользователя, чтобы лишний раз не бегать, забирайте сразу пользователей с их книгами. При этом в Book оставить ленивую загрузку пользователей.

Тогда в jsp вы идете по пользователям и у каждого их них проходите по книгам.

  <c:forEach items="${listUsers}" var="user" >
      <c:foreach items="${user.booksOrders}" var="book">
        //тут в таблицу вкладываете значения
        //userName = <c:out value="${user.name}"/>
        //BookAuthor = <c:out value="${book.bookAutor}"/>
        //BookTitle = <c:out value="${book.bookTitle}"/>
      </c:foreach>
  </c:foreach>

Этот кусок корректируете исходя из требований оформления.

также после первого foreach можно написать

 <jsp:useBean id="user" class="package.User.class">

Если работаете через IDEA Ultimate это добавит интеграцию, т.е. оперировать вы будете не Object, а объектом конкретного класса.

id - название переменной на jsp странице class - класс которому принадлежит объект.

Если не хотите убирать ленивую загрузку, то просто перед отправкой листа на страницу пройдитесь по всем пользователям и загрузите книги.

READ ALSO
JavaX Swing. Шашки

JavaX Swing. Шашки

Всем привет! Хотел сделать игру Шашки в JavaX SwingСейчас использую картинку для доски шашки (пустая простая доска (черные и белые))

243
Вычислить выражение, записанное в String

Вычислить выражение, записанное в String

Писал я графический калькулятор и пришла идея записать все выражение в String, то есть пользователь набирает кнопками, то что ему нужно решить,...

370
SQLJ в Java (Intellij idea)

SQLJ в Java (Intellij idea)

ЗдравствуйтеПодскажите, какую библиотеку нужно скачать, или нечто подобное, чтобы работал import oracle

217