0

这里我们有一个清单类,其中包括学生和教师的列表,两者都可以为空。

class Manifest{
    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "MANIFEST_STUDENT")
    List<String> students = new ArrayList<String>();

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "MANIFEST_TEACHER")
    List<String> teachers = new ArrayList<String>();;

    @ElementCollection(fetch = FetchType.EAGER)
    @CollectionTable(name = "MANIFEST_OTHERS")
    List<String> others = new ArrayList<String>();;
}

在 UI 上,有两个multiple select,一个用于student,一个用于teacher让用户选择当前清单。

这是问题所在:

当用户deselect全部studentsteachers从列表中(意味着从当前删除所有学生或教师manifest)并单击保存时,不幸的是,从 UI 和数据库中无法保存任何内容,它显示multiselect所选的外观与SAME以前一样。

从服务层看,代码就是这样。

manifest.merge();

看来我们必须保留at least one学生或教师的收藏字段才能使更改有效。那么这里发生了什么,解决方案是什么?顺便说一句,我们在 Openjpa 上。

4

2 回答 2

1

解决问题,更像是一种解决方法:

在调用之前merge(),放置几个条件检查器以确保集合字段不为空

public void save(Manifest entity) {

    if(entity.getStudents()==null){
        entity.setStudents(new ArrayList<String>());
    }

    if(entity.getTeachers()==null){
        entity.setTeachers(new ArrayList<String>());
    }

    if(entity.getOthers()==null){
        entity.setOthers(new ArrayList<String>());
    }

    entity.merge();
}

尽管很简单,但 UI 似乎将这些集合字段返回为 null,即使我们将它们启动为空字符串列表也是如此。

干杯。

于 2013-06-24T17:27:27.910 回答
0

初始化 JPA 托管类中的值(例如 )与class ManifestJPA 将创建类的内容或方式无关,因为 JPA 将提取的行映射到类。特别是,结果:

List<String> students = new ArrayList<String>();

很可能是:

  • 在创建(通过 JPA)新实例时,分配一个ArrayList<String>()to students
  • JPAstudents用它提取的数据覆盖 - 空ArrayList的被取消引用/丢失。

如果您的代码正在清除列表,例如students,请使用obj.getStudents().clear(). 如果您调用obj.setStudents(someEmptyList).

这里的问题是 JPA 管理器如何处理空数据集:作为null或作为空列表。JPA 规范(旧的,不确定刚刚发布的更新)在这一点上没有立场。这里有一篇相关文章

从您的评论中,很明显 OpenJPA 可能不尊重/的null值,而当值设置为空列表时,它很乐意管理必要的更改。在这个阶段,比我更了解 OpenJPA 的人可能无法提供帮助 - 同时您有一个解决方法。CollectionList

于 2013-06-24T21:05:58.203 回答