Hibernate 使用不可变列表初始化集合

Ste*_*ann 6 java hibernate jpa

我有以下实体:

@Entity(name = "courses")
public class Course {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Singular
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Collection<Comment> comments = new ArrayList<>();

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private User createdBy;

    public void addComment(Comment comment) {
        comments.add(comment);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我从数据库加载课程时,评论将使用持久包进行初始化。当我调用 时出现问题addComment(comment),然后出现此异常:

Caused by: java.lang.UnsupportedOperationException: null
    at java.base/java.util.AbstractList.add(AbstractList.java:153) ~[na:na]
    at java.base/java.util.AbstractList.add(AbstractList.java:111) ~[na:na]
    at org.hibernate.collection.internal.PersistentBag.add(PersistentBag.java:408) ~[hibernate-core-5.4.18.Final.jar:5.4.18.Final]
Run Code Online (Sandbox Code Playgroud)

看来休眠分配的 Persistant Bag 是一个Collection.EmptyList不可变的,因此无法添加任何注释。

我需要更改什么才能添加评论?

Ste*_*ann 4

好吧,看起来 lombok 和 hibernate 并没有像我预期的那样真正协同工作。此外,我还用以下 lombok 符号对我的实体进行了注释:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Course {

    //...
    
    @Singular
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Comment> comments = new ArrayList<>();
}
Run Code Online (Sandbox Code Playgroud)

当我从数据库加载实体时,lombok 似乎使用构建器模式来创建新实例。这将导致注释分配有 Collection.EmptyList,然后无法添加新注释,因为它是不可变的。我的修复是删除@Singular并添加@Builder.Default. 现在 anew ArrayList<>()被分配给不可变列表。现在我无法使用创建的单一构建器方法,但至少它可以工作。