[英]Hibernate/JPA/Spring Problems with persisting (sorted) collection
本來我想把這個寫成一個問題,但是在寫這篇文章時,我找到了一個解決方案。 如果這里有人有更好的,因為我的有點丑,請隨時發布。 否則,我只會將我的解決方案存檔在這里,以便其他面臨類似問題的人知道。 (解決方案可以在底部找到。)
我有以下需求需要滿足:
結果應如下所示:
[x] aaaModule
[x] AbbModule
[x] aBcModule
[ ] aabModule
[ ] acbModule
請注意,排序需要不區分大小寫,這就是 @OrderBy 不剪切的原因。 相反,我實現了要排序的實體類的 Comparable 接口,並在 @ManyToMany 映射上使用了 Hibernate 的 @SortNatural-Annotation。
我目前的解決方案(當然是簡化的)如下所示:
在 Information.java 實體中:
@ManyToMany
@JoinTable(
name = "bla_modules",
schema = "blaSchema",
joinColumns = { @JoinColumn(name = "bla_info_id") },
inverseJoinColumns = { @JoinColumn(name = "bla_module_id") }
)
@SortNatural
private Set<Module> modules = new TreeSet<>();
在 Controller.java 中(在 GET-Mapping 中):
Set<Module> modulesToDisplay = new LinkedHashSet<>();
modulesToDisplay.addAll(currentInformation.getModules());
modulesToDisplay.addAll(moduleRepository.findByIdGreaterThanOrderByLabelAsc(0));
model.addAttribute("modulesToDisplay", modulesToDisplay);
在 info.jsp 里面:
<form:form method="POST" action="/informations.bla/editInformation" modelAttribute="currentInformation">
<ul style="list-style-type:none">
<c:forEach items="${modulesToDisplay}" var="module">
<li>
<div class="inline">
<form:checkbox path="modules" value="${module}" label="[${module.shortLabel}] ${module.label}"/>
</div>
</li>
</c:forEach>
</ul>
<input type="submit" value="Save">
</form:form>
在 Controller.java 中(POST-Mapping):
public String editInformation(@ModelAttribute Information submittedInformation) {
Information informationAfterSaving = informationRepository.save(submittedInformation);
在我在集合上使用 @SortNatural 注釋之前,這一切都很好,但在這種情況下,JPA 在從數據庫加載 TreeSet 時沒有對 TreeSet 進行排序。
如果我從數據庫加載現有的信息實體,顯示它,更改屬性,然后將其保存回來,它仍然可以很好地工作。
但是,當我加載一個新的信息實體時,它剛剛通過“新信息()”在控制器中創建,當 GET-Mapping 沒有收到要加載的有效 ID 時,我突然收到錯誤java.lang.ClassCastException: class java.util.LinkedHashSet cannot be cast to class java.util.SortedSet
當Information informationAfterSaving = informationRepository.save(submittedInformation);
時java.lang.ClassCastException: class java.util.LinkedHashSet cannot be cast to class java.util.SortedSet
Information informationAfterSaving = informationRepository.save(submittedInformation);
在控制器的 POST-Mapping 中執行。
解決方案可以在下面我自己的答案中找到。 我希望有一天它可以幫助某人。
再見
在調用 Repository 的 .save 方法之前,在 Controller 的 POST-Mapping 中,只需執行以下操作:
submittedInformation.setModules(new TreeSet<Module>(submittedInformation.getModules()));
現在我覺得有點愚蠢,因為我之前沒有想到這個明顯的解決方案,不會撒謊。
不過,該解決方案仍然有點難看,所以如果有人知道如何告訴 JPA/Hibernate 將接收到的 Spring 集合正確地轉換回 TreeSet,或者告訴 Spring 以 TreeSet 的形式附加 Checkbox-Collection,那么請告訴我。
對我來說不是一個合適的解決方案,但@MartinFrey 也提供了一個可能的解決方案:只需跳過后端的排序,而是在 GUI 端排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.