【发布时间】:2020-05-07 07:57:08
【问题描述】:
我有 spring-data-rest 项目,其中有一些实体,例如名为Aaa。这是简化的定义:
@Entity
@Data // some lombok-project magic for getters/setters/...
public class Aaa {
// many different fields
/**
* bi-directional many-to-one association to Bbb
*/
@ManyToOne(optional = true)
@JoinColumn(name="bbb_fk")
@RestResource(
description = @Description("Optional relation of Aaa to Bbb. " +
"If not empty, it means that this Aaa belongs to the given Bbb. " +
"Otherwise given Aaa is just something like a template."
))
private Bbb bbb;
// also some other references, like:
private List<Ccc> cccs;
}
我需要(根据业务规则)确保设置 Bbb 引用将导致数据库中给定实体的副本,并且只有副本才会设置给定引用。写时复制语义。将引用从某个 Bbb 实例更改为其他实例,不会触发副本。
请注意,Aaa 实体和 Bbb 实体确实有它们的 interface AaaRepository extends PagingAndSortingRepository<Aaa, Long> 和 BbbRepository。这意味着当使用 HAL 表示时,Aaa 实例在其主体中确实只有与 Bbb 的关联链接。
目标/目标:
我已经在表中存储了 Aaa 实例的“模板”(例如 Aaa 实例,具有 Aaa.bbb == null)以及 Aaa 的“真实”实例(例如 Aaa.bbb 不为空)。在创建 Aaa 的“真实”实例时,总是使用一些 Aaa 模板来完成。从空值设置 Aaa.bbb 时,我想复制给定的 Aaa 并将 Aaa_copy.bbb 设置为所需的值。同样返回的休息资源必须是新创建的副本(即为 ID 为 /api/aaa/123 的休息资源设置关联将返回具有不同 ID 的实例!)。
我想到的可能的解决方案。我没有实现它们中的任何一个,我只是想选择正确的实现方法:
- 为关联链接实现自定义控制器(即 /api/aaa/{id}/bbb 用于 POST 和 PUT。可能的问题 with "hiding" 可能很容易解决。
- 覆盖存储库中的
S save(S s)和 saveAll 方法并在那里执行“如果需要则克隆”魔法 - 在 Aaa 类中实现方法并使用
@PrePersist注释对其进行注释。
我应该在哪里(以及为什么在那里)实施这种行为?
【问题讨论】:
-
在这段摘录中
private Release release应该是private Bbb bbb对吗?如果您错过了这一点,请在您的问题中更正这一点。此外,您的目标对我来说还不是很清楚。是否正确,在更改Bbb引用时,您想要创建Aaa对象(当前正在更改)的副本,然后保存该引用?那么Aaa对象的某种版本控制?
标签: spring-data-rest spring-hateoas