【问题标题】:Insert cascade with @RepositoryRestResource, foreign key always null使用@RepositoryRestResource 插入级联,外键始终为空
【发布时间】:2018-12-27 16:17:30
【问题描述】:

也许我很幸运,但我正在尝试使用@RepositoryRestResource 实现一个存储库,但是父级的外键未在子级中设置。我会尝试解释我做了什么以及我发现了什么..

首先让我们展示一下我做了什么:

UML:

我的土豆实体:

@Data
@Entity
@Table(name = "POTATO")
public class PotatoEntity {
    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private BigInteger id;

    @Column(name = "FIRSTNAME")
    private String firstname;

    @Column(name = "LASTNAME")
    private String lastname;

    @OneToMany(mappedBy = "potato", cascade = CascadeType.PERSIST)
    private List<DetailPotatoEntity> detailPotatoList;
}

我的 DetailPotato 实体:

@Data
@Entity
@Table(name = "DETAIL_POTATO")
public class DetailPotatoEntity {
    @Id
    @Column(name = "ID")
    private BigInteger id;

    @Column(name = "WEIGHT")
    private BigDecimal weight;

    @Column(name = "HEIGHT")
    private BigDecimal height;

    @JoinColumn(name = "POTATO_ID", nullable = false)
    @ManyToOne
    @JsonBackReference(value = "potato-detailPotato")
    private PotatoEntity potato;
}

我的土豆仓库:

@RepositoryRestResource(collectionResourceRel = "potatos", path = "potatos")
public interface PotatoRepository extends CrudRepository<PotatoEntity, BigInteger> {
}

问题是,当我推送以下 json 时:

{
    "firstname":"patate",
    "lastname":"potato",
    "detailPotatoList": [
            {
                "weight":12,
                "height":13
            }
        ]
}

DETAIL_POTATO 中的 POTATO_ID 始终为空。通常,当您拥有自己的控制器和服务时,您会在每个DetailPotatoEntity 中设置PotatoEntity,一切都会好起来的。所以,我会坚持 @RepositoryRestResource 会为我做这件事。但事实并非如此。


我是如何“解决”它的?还是我?:

@PrePersist
public void prePersist() {
    detailPotatoList.forEach(detailPotato-> detailPotato.setPotato(this));
}

public void setDetailPotatoList(List<DetailPotato> detailPotatoList) {
    detailPotatoList.forEach(detailPotato-> detailPotato.setPotato(this));
    this.detailPotatoList = detailPotatoList;
}

我的问题是,我必须这样做是否正常? @RepositoryRestResource 应该自己管理吗?


这是我的观察:

-也许@RepositoryRestResource 应该只用于一个实体?

-我尝试使用 DetailPotatoRepository 只是为了看看(如果您自己检查,请注意您需要删除 @RepositoryRestResource 注释的 PotatoRepository 才能工作):

@RepositoryRestResource(collectionResourceRel = "detailsPotato", path = "detailsPotato")
public interface DetailPotatoRepository extends CrudRepository<DetailPotatoEntity, BigInteger> {
}

当我推送以下 json 时:

{
    "weight":12,
    "height":13,
    "potato": {
        "firstname":"pomme",
        "lastname":"apple"
    }
}

POTATO_ID 已设置,一切正常。


结论

当父母告诉他的孩子坚持时,孩子不知道他的父母是谁。但是,当孩子告诉他的父母坚持时,孩子就会知道他的父母。

问题又来了:@RepositoryRestResource 是否应该自行管理?或者@RepositoryRestResource 应该只用于一个实体?

【问题讨论】:

    标签: hibernate spring-boot jpa spring-data-rest


    【解决方案1】:

    您正在使用双向关联。在这种情况下,您应该提供您的实体的synchronization。尝试在您的Potato#detailPotatoList setter 中实现这一点。比如这样:

    public void setDetailPotatoList(List<DetailPotatoEntity> details) {
        if (detailPotatoList != null) {
            detailPotatoList.forEach(d -> d.setPotato(null));
        }
        if (details != null) {
            details.forEach(d -> d.setPotato(this));
        }
        detailPotatoList = details;
    } 
    

    见我的example

    附加提示:hibernate-enhance-maven-plugin

    【讨论】:

    • 我知道,这就是为什么我有一个部分 how I "solved" it我>。我的观点更多的是:@RepositoryRestResource 应该管理双向吗?因为手动,我会做你所做的。
    • @GabLeg 不幸的是 SDR 作者doesn't like 双向关联.. (
    • 那个链接是我需要的!我想我没有用好词搜索..谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 2015-06-15
    • 1970-01-01
    • 2022-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多