我想創建一個ul具有li每個review在Set<Review> reviews從book我發送從服務器回傳的物件。結果似乎是一個巨大的內部服務器錯誤,我在終端上列印了很長的堆疊跟蹤,我不知道可能是什么問題。如果我注釋掉該ul塊,則一切正常。
錯誤(打開新鏈接,pastebin)(不是完整錯誤,它不適合 VSCODE 終端。
book.html
<div class="container" style="width: 100%; padding-top: 25px; display: flex; justify-content: center;">
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="..." alt="Card image cap">
<div class="card-body">
<h5 th:text="${book.name}" class="card-title">Book name here.</h5>
<p th:text="${book.author}" class="card-text">Author name here.</p>
<p th:text="${book.isbn}" class="card-text">ISBN number here.</p>
</div>
<ul class="list-group list-group-flush">
<li th:each="review : ${book.reviews}" th:text="${review.review}" class="list-group-item">Review goes here.</li>
</ul>
</div>
</div>
BookController.java
package com.domain.congregentur.book;
import ...
@Controller
@RequestMapping("api/books")
public class BookController {
public BookService bookService;
@Autowired
public BookController(BookService bookService) {
this.bookService = bookService;
}
...
@GetMapping("/{id}")
public String find(@PathVariable("id") Long id, Model model) {
Optional<Book> book = bookService.findById(id);
if (book.isPresent()) {
model.addAttribute("book", book.get());
return "book";
}
return "books";
}
...
}
Book.java
package com.domain.congregentur.book;
import ...
@Entity
@Table(name = "Books")
@EqualsAndHashCode
@ToString
@Getter
@Setter
public class Book implements Serializable {
@Id
@SequenceGenerator(name = "book_sequence", sequenceName = "book_sequence", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "book_sequence")
private Long id;
@NotNull
private String isbn;
@NotNull
private String name;
@NotNull
private String author;
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "book")
private Set<Review> reviews;
Book() {
}
public Book(Long id, String isbn, String name, String author) {
this.id = id;
this.isbn = isbn;
this.name = name;
this.author = author;
}
public Book(String isbn, String name, String author) {
this.isbn = isbn;
this.name = name;
this.author = author;
}
public Book updateWith(Book book) {
return new Book(
this.id,
book.isbn,
book.name,
book.author);
}
}
Review.java
package com.domain.congregentur.review;
import ...
@Entity
@Table(name = "Reviews")
@EqualsAndHashCode
@ToString
@Setter
@Getter
public class Review {
@Id
@SequenceGenerator(name = "review_sequence", sequenceName = "review_sequence", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "review_sequence")
private Long id;
@NotNull
private String review;
@ManyToOne
@JoinColumn(name = "isbn", referencedColumnName = "isbn")
private Book book;
Review() {
}
public Review(String review, Book book) {
this.review = review;
this.book = book;
}
}
可能值得一提的是,這就是我將一些隨機測驗資料實體化到我的資料庫進行測驗的方式,我不知道這是否是一種合適的方法,它可能與問題相關,也可能無關。請隨時教育我。
DataLoader.java
package com.domain.congregentur.dataloader;
import ...
@Component
public class DataLoader implements ApplicationRunner {
private BookRepository bookRepository;
private ReviewRepository reviewRepository;
@Autowired
public DataLoader(BookRepository bookRepository, ReviewRepository reviewRepository) {
this.bookRepository = bookRepository;
this.reviewRepository = reviewRepository;
}
public void run(ApplicationArguments args) {
Book b1 = new Book("9780812969641", "In Search of Lost Time", "Marcel Proust");
Book b2 = new Book("9781772267143", "Swann's Way", "Marcel Proust");
Book b3 = new Book("9780099469698", "Don Quixote", "Miguel de Cervantes");
bookRepository.saveAll(List.of(b1, b2, b3));
List<Review> reviews = List.of(
new Review("Book1 -> Review1", b1),
new Review("Book1 -> Review2", b1),
new Review("Book2 -> Review1", b2),
new Review("Book2 -> Review2", b2),
new Review("Book3 -> Review1", b3),
new Review("Book3 -> Review2", b3));
reviewRepository.saveAll(reviews);
}
}
After having looked at the stack trace for a bit, it is seemingly repeating the following part but with slightly different numbers at some specific places.
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:591) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:149) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:458) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at com.domain.congregentur.book.Book.hashCode(Book.java:26) ~[classes/:na]
at com.domain.congregentur.review.Review.hashCode(Review.java:22) ~[classes/:na]
at java.base/java.util.HashMap.hash(HashMap.java:340) ~[na:na]
at java.base/java.util.HashMap.put(HashMap.java:608) ~[na:na]
at java.base/java.util.HashSet.add(HashSet.java:220) ~[na:na]
at java.base/java.util.AbstractCollection.addAll(AbstractCollection.java:352) ~[na:na]
at org.hibernate.collection.internal.PersistentSet.endRead(PersistentSet.java:355) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:239) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:224) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.engine.loading.internal.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:198) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.loader.plan.exec.process.internal.CollectionReferenceInitializerImpl.endLoading(CollectionReferenceInitializerImpl.java:154) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishLoadingCollections(AbstractRowReader.java:232) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:190) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:96) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:105) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:87) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:705) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:76) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2203) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:595) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:264) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final]
uj5u.com熱心網友回復:
這是因為您使用的是@EqualsAndHashCodeLombok 注釋。獲取 Review JPA 物體的哈希碼時出現錯誤(可能是遞回的,因為您的堆疊跟蹤很大,我不確定)。
Review 物體中 Lombok 自動生成的 hashcode 方法將呼叫 Book 物體,該物體嘗試獲取 Set of Reviews 的 hashcode。這個 Set 需要先初始化,然后才能讀取。
at com.domain.congregentur.book.Book.hashCode(Book.java:26) ~[classes/:na]
at com.domain.congregentur.review.Review.hashCode(Review.java:22) ~[classes/:na]
您可以使用 2 個選項解決此問題。
- 您可以自己實作 hashcode 和 equals 方法,僅使用主鍵和物件的屬性。
這是一篇很好的文章,詳細解釋了。
https://thorben-janssen.com/lombok-hibernate-how-to-avoid-common-pitfalls/#Don8217t_Use_EqualsAndHashCode
- 您可以使用 Lombok 注釋,但要確保以正確的方式使用 equals、hashcode 和 Getter/Setter 方法。這里有 2 個答案,詳細介紹了這個主題。
龍目島與休眠
如何創建安全的 Lombok JPA 物體?
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/395178.html
