首页 > 解决方案 > 使用 spring-data-jdbc 保存具有一对多关系的实体返回空列表

问题描述

在 Spring Data JDBC 中保存具有ArticleList一对多关系( )的项目()后,返回值存在问题。ArticleListEntry第一次创建实体时,调用repository.save(entity)我的返回实体时,包括所有相关项目,都正确保存在数据库中。但是,返回的值包含 的空列表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>的第一次调用, an 会收到相同的 entity-with-empty-list 。仍然包含文章。save(articleList)persistedEntityentity

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

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

标签: javarelationshipoptimistic-lockingspring-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;
}

推荐阅读