I have spring-data-rest project, where I have some entity, for example called Aaa
. It's simplified definition:
@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;
}
I need (by business rule) ensure that setting Bbb reference will lead to the copy of the given entity in database and only copy will have set given reference. Copy-on-write semantics. Change of reference from some Bbb instance to other, does not trigger a copy.
Note, that Aaa entities and also Bbb entities does have their interface AaaRepository extends PagingAndSortingRepository<Aaa, Long>
and BbbRepository
. It means that when using HAL representation, Aaa instance does have just association link to Bbb in its body.
Objective/ goal:
I have stored "templates" of Aaa instances in table (such Aaa instance, that have Aaa.bbb == null) and also "real" instances of Aaa (such will have Aaa.bbb not null). When creating "real" instance of Aaa, it is ALWAYS done by using some Aaa template. When setting Aaa.bbb from null value, I would like to make copy of given Aaa and set Aaa_copy.bbb to required value. Also returned rest resource have to be a newly created copy (i.e. setting association for rest resource with ID /api/aaa/123
will return instance with different id!).
Possible solutions I have think of. I have not implemented any of them, I just want to choose right approach for implementation:
- Implement custom controller for associative link (i.e. /api/aaa/{id}/bbb for POST and PUT. Possible problem with "hiding" can be solved perhaps easily.
- override
S save(S s)
and saveAll method in repository and do "clone if needed" magic there - implement method in Aaa class and annotate it with
@PrePersist
annotation.
Where (and why there), should I implement such behavior?