起初我想把这当作一个问题来写,但在写这篇文章时,我找到了一个解决办法。如果有人在这里有一个更好的,因为我的有点难看,请随意张贴。否则,我将把我的解决方案存档在这里,以便其他面临类似问题的人知道(可在底部找到解决方案。)
我有以下需要满足的要求:
在网页上显示所有带有复选框的“模块”
按两个子集对模块进行排序:
要在顶部显示的子集:所有被选中的模块,因此保存在信息实体的“模块”集合中
要在下面显示的子集:尚未选择(id>0)并直接从数据库检索的所有模块
按字母顺序对这些子集进行排序(不区分大小写)
结果应该是这样的:
[x] aaaModule
[x] AbbModule
[x] aBcModule
[ ] aabModule
[ ] acbModule
请注意,排序需要不区分大小写,这就是@orderby不剪切它的原因。相反,我实现了与要排序的实体类相当的接口,并在@manytomanyMap上使用了hibernate的@sortnural注解。
我目前的解决方案(当然是简化的)如下所示:
在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中(在getMap中):
Set<Module> modulesToDisplay = new LinkedHashSet<>();
modulesToDisplay.addAll(currentInformation.getModules());
modulesToDisplay.addAll(moduleRepository.findByIdGreaterThanOrderByLabelAsc(0));
model.addAttribute("modulesToDisplay", modulesToDisplay);
在information.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(postMap)中:
public String editInformation(@ModelAttribute Information submittedInformation) {
Information informationAfterSaving = informationRepository.save(submittedInformation);
在我对集合使用@sortnatural注解之前,这一切都非常有效,但是在这种情况下,jpa在从数据库加载树集时没有对树集进行排序。
如果我从数据库中加载一个现有的信息实体,显示该实体,更改属性,然后将其保存回来,它仍然可以工作得很好。
但是,当我加载一个新的信息实体时,它是通过“new information()”在控制器中创建的,当getMap没有收到要加载的有效id时,我突然得到了错误 java.lang.ClassCastException: class java.util.LinkedHashSet cannot be cast to class java.util.SortedSet
当 Information informationAfterSaving = informationRepository.save(submittedInformation);
在内部执行控制器的postMap。
解决办法可以在下面我自己的答案中找到。我希望有一天它能帮助别人。
再见
1条答案
按热度按时间guykilcj1#
解决方案
在调用存储库的.save方法之前,在控制器的postMap中,只需执行以下操作:
我觉得自己有点傻,因为我之前没有想到这个明显的解决办法,我不想撒谎。
不过,这个解决方案还是有点难看,所以如果有人知道如何告诉jpa/hibernate将从spring-back接收的集合正确地转换为树集,或者告诉spring以树集的形式附加checkbox集合,那么请告诉我。
备选方案
这不是一个适合我的解决方案,但是@martinfrey也给出了一个可能的解决方案:跳过后端的排序,而是在gui端进行排序。