在 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
我在 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