保存与 spring-data-jdbc returns 空列表具有一对多关系的实体

Saving entity with one-to-many relations with spring-data-jdbc returns empty list

在 Spring 数据 Spring 中保存具有一对多关系 (ArticleListEntry) 的项目 (ArticleList) 后,return 值出现问题 JDBC。首次创建实体时,调用 repository.save(entity) 后,我的 return 实体(包括所有相关项)都正确保存在数据库中。但是,returned 值包含 entries 的空列表。原始 ArticleList 上的字段始终填写正确。

我有以下实体:

@Table("article_list_meta")
@Data
public class ArticleList {
    @Id
    private final Long id;
    @Version
    private long version;
    @MappedCollection(idColumn = "list_id", keyColumn = "seq")
    private List<ArticleListEntry> entries = new ArrayList<>();  
    
    @PersistenceConstructor
    public ArticleList(Long id, String publication, String name) {
        this.id = id;
        this.publication = publication;
        this.name = name;
    }
    public ArticleList(String publication, String name) {
        this(null, publication, name);
    }
    // other fields
}

@Data
@Table("article_list_entry")
public class ArticleListEntry {

    @Column("article_id")
    private final long articleId;

}

有存储库

@Repository
public interface ArticleListRepository extends CrudRepository<ArticleList, Long> {}

我坚持使用

        ArticleList entity = repository.findByPublicationAndName(publication, name)
                .orElseGet(() -> new ArticleList(publication, name));
        entity = mapper.fromDto(entity, list, fieldsToUpdate);
        ArticleList persistedEntity = repository.save(entity);

初始 (version == 0) 保存后,所有后续更新都包含所有相关项目。 请注意,AbstractRelationalEventListener<ArticleList> 在第一次调用 save(articleList) (persistedEntity) 时会收到相同的空列表实体。 entity 仍然包含文章。

这让我相信我偶然发现了一个错误,但由于这是我们第一个使用 data-jdbc 而不是 data-jpa 的项目,我的实体中也可能有问题。

我正在使用 Spring Boot 2.3.6.RELEASE 版本 2.0.5.RELEASE of spring-data-jdbc.

这是 entries 不属于持久性构造函数的结果。

当构造函数用于创建实例的副本时(例如,因为需要设置 id),只会复制该构造函数中包含的属性。

因此,为了解决该问题,您应该将 ArticleList 的构造函数修改为如下所示:

@PersistenceConstructor
public ArticleList(Long id, String publication, String name, List<ArticleListEntry> entries) {
    this.id = id;
    this.publication = publication;
    this.name = name;
    this.entries = entries;
}