在 Boot 中,我们经常将@OneToMany
这样的实体关系Map到1:M这样的数据库关系。
如果我们有一个像Car和Part这样的实体,其中Car是关系的一端,Part是关系的M端,这是很好的。在这种情况下,这是很好的,因为两个表中的数据是“相关的”,我们希望一次从两个表中插入或提取相关数据。
在本例中,我们的Car实体将具有OneToMany,如:
@Entity(name = "car")
public class CarEntity {
...
@Id @GeneratedValue(...)
private Long id;
@OneToMany(mappedBy = "carDetails", cascade = CascadeType.ALL)
private List<PartEntity> parts;
}
和部件实体的“多对一”,如:
@Entity(name = "part")
public class PartEntity {
...
@ManyToOne
@JoinColumn(name = "car_id")
private CarEntity carDetails;
}
,而这是罚款。
为了持久保存日期,我们必须提供一个JSON有效负载,在有效负载中保存**Car及其Parts的数据,以便保存Car和Parts:
{
"vendor": "Toyota",
"model": "Camry"
"parts": [
{
"gasket": "A103",
"price": "16"
},
{
"tire": "Good year",
"price": "149"
}
]
}
,这会将汽车及其部件保存到存储库中。
检索时相同。检索汽车也会检索其零件。
一切都清楚了。
然而,我们可能有一个1:M关系,其中M中的数据与关系的1方中的数据“有点不相关”。
例如,假设我们出于审计目的记录事件。每个事件都记录在EVENT表中。但我们还希望将此事件转发给某个下游API,因此我们还在EVENT_LOG表中记录事件是否发送给此下游API。
因此,我们有EVENT:EVENT_LOG 1:M关系,其中一个EVENT可以有多个EVENT_LOG。在这种情况下,EVENT_LOG是“不相关的”,因为它只是用于日志记录/审核目的的数据,不应是POST或GET请求中JSON有效负载的一部分。
假设我们有这些表定义:
EVENT[ID (PK), NAME, DATE]
EVENT_LOG[ID (PK), EVENT_ID (FK), SENT, DATE]
上面,PKs和DATEs字段由数据库处理,SENT字段默认为0表示尚未发送(1 =已发送),例如:
EVENT [1, 'save_data_event', 2022-10-12T15:17:001]
EVENT_LOG [1, 1, 0, 2022-10-12T15:17:002] // 0 = default (not sent)
这里,我们希望发送仅包含相关EVENT数据的JSON有效负载:
{
"vendor": "some_data_event"
}
这将填充如上所述的EVENT表。但是,在实体类中使用上述@OneToMany关系,它不会填充EVENT_LOG中的数据,这不是我们想要的。我们希望它们都被填充。
类似地,在获取数据时,我们只需要EVENT表中的相关数据,因为EVENT_LOG数据不是我们感兴趣的数据,并且不应将其包含在JSON GET有效负载中。
如何才能做到这一点?
1条答案
按热度按时间os8fio9y1#
假设您使用Jackson,您可以使用
@JsonIgnore
来忽略JSON生成的属性。正确的做法是按照域驱动设计的建议将域模型分解为聚合,并且在聚合之间只引用id。I wrote an article about this in the context of Spring Data JDBC,但是这个概念也可以并且可以说应该应用于JPA。