在 Spring 数据 REST 中将 parent 和 child 实体公开为 REST 存储库

Exposing both parent and child entities as REST repositories in Spring Data REST

我在 Spring 日期 REST 存储库中配置了一个 parent child 实体。 parent 看起来像这样

@Entity
@Table(name = "DPST_DTL")
public class Deposit {

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "deposit", orphanRemoval=true)
    private List<Instrument> instrumentList = new ArrayList<Instrument>();
}

child 看起来像这样:

@Entity
@Table(name = "INSTR_DTL")
public class Instrument {

    @ManyToOne
    @JoinColumn(name = "DPST_ID")
    @JsonBackReference
    private Deposit deposit;
}

我已经为存款定义了一个 RepositoryRestresource 如下:

@RepositoryRestResource(collectionResourceRel = "deposit", path = "deposit")
public interface DepositRepository extends PagingAndSortingRepository<Deposit, Long>{

}

和 Instrument 相同的如下:

@RepositoryRestResource(collectionResourceRel = "instrument", path = "instrument")
public interface InstrumentRepository extends PagingAndSortingRepository<Instrument, Long>{

}

如果我尝试 POST parent 一些 child 记录,我会收到如下消息: "message": "Failed to convert from type [java.net.URI] to type [com.XXX.irh.insprc.instrument.Instrument] for value 'countryCode'; nested exception is java.lang.IllegalArgumentException: Cannot resolve URI countryCode. Is it local or remote? Only local URIs are resolvable." },

"countryCode" 恰好是 child JSON

中的第一个字段

如果我用一些 children 查询 parent,结果 JSON 不会扩展 children 并且只显示 link像这样: "instrumentList":{"href":“http://localhost:9090/deposit/8/instrumentList”}

但是,如果我将 child 存储库标记为 exported=false,我就可以解决这个问题。但是 child 实体无法通过 REST API 公开。

问题是:

我是否可以公开 parent 和 child 实体的基本 CRUD 功能,而无需编写自定义控制器等?

我明白,根据 DDD 最佳实践,我的 parent 是一个应该通过 REST 存储库公开的聚合,但不幸的是,我确实有一些用例,我需要为两者提供独立的 CRUD 功能。

您可以使用 projections:

@Projection(name = "withInstruments", types = Person.class)
public interface WithInstruments {

   @Value("#{target.depositName}")
   String getDepositName();

   List<Instrument> getInstrumentList();  
}

然后您可以将您的实体放在一起:

GET /deposits?projection=withInstruments
{
   "depositName": "deposit1",
   "instrumentList": [
       {
           "intrumentName": "instrument1",
       },
       {
           "intrumentName": "instrument1",
       }
   ]
}

额外info