hibernate/jpa/spring关于持久(排序)集合的问题

xmd2e60i  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(361)

起初我想把这当作一个问题来写,但在写这篇文章时,我找到了一个解决办法。如果有人在这里有一个更好的,因为我的有点难看,请随意张贴。否则,我将把我的解决方案存档在这里,以便其他面临类似问题的人知道(可在底部找到解决方案。)
我有以下需要满足的要求:
在网页上显示所有带有复选框的“模块”
按两个子集对模块进行排序:
要在顶部显示的子集:所有被选中的模块,因此保存在信息实体的“模块”集合中
要在下面显示的子集:尚未选择(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.SortedSetInformation informationAfterSaving = informationRepository.save(submittedInformation); 在内部执行控制器的postMap。
解决办法可以在下面我自己的答案中找到。我希望有一天它能帮助别人。
再见

guykilcj

guykilcj1#

解决方案

在调用存储库的.save方法之前,在控制器的postMap中,只需执行以下操作:

submittedInformation.setModules(new TreeSet<Module>(submittedInformation.getModules()));

我觉得自己有点傻,因为我之前没有想到这个明显的解决办法,我不想撒谎。
不过,这个解决方案还是有点难看,所以如果有人知道如何告诉jpa/hibernate将从spring-back接收的集合正确地转换为树集,或者告诉spring以树集的形式附加checkbox集合,那么请告诉我。

备选方案

这不是一个适合我的解决方案,但是@martinfrey也给出了一个可能的解决方案:跳过后端的排序,而是在gui端进行排序。

相关问题