I’ve encountered this problem that won’t let me sleep
I have 2 entities Property and Tenant
each property can have 0..1 tenant, each tenant can have 1..N properties
// some annotations public class Tenant { // more fields @OneToMany(mappedBy = "tenant", cascade = CascadeType.MERGE, fetch = FetchType.EAGER) private Set<Property> properties = new HashSet<>(); } // some annotations public class Property { // more fields @ManyToOne(fetch = FetchType.LAZY) private Tenant tenant; }
what am I trying to accomplish is when I create a new tenant, using cascading I want to attach it to an existing property
saving is done via JpaRepository.save(Tenant)
for example first I create new Property
{ // more fields "tenant": null }
then sometime later I decide I want to create a tenant for this property
{ // more fields "properties": [ { "id": 1, // property id I want to create this tenant for "tenant": null } ] }
I believe I’ve tried every cascade type (except ALL and PERSIST, these 2 can’t be used with detached entities)
How would it be possible to synchronize a newly created tenant with an already existing property?
I read about this that CascadeType.MERGE should do the trick but it does not for me
Any help is appreciated Thanks in advance
edit: all getters and setters are generated by lombok
rest resource for saving
@PostMapping public ResponseEntity<Void> saveTenant( @Valid @RequestBody TenantDto tenantDto, UriComponentsBuilder uriComponentsBuilder) { log.info(tenantDto.toString()); Long id = tenantService.saveTenant(tenantDto); URI location = uriComponentsBuilder.path("/api/tenants/{id}").buildAndExpand(id).toUri(); return ResponseEntity.created(location).build(); }
service
@Override public Long saveTenant(TenantDto tenantDto) { // mapstruct mapping return tenantRepository.save(tenantMapper.toEntity(tenantDto)).getId(); }
repo
@Repository public interface TenantRepository extends JpaRepository<Tenant, Long> {}
Advertisement
Answer
Cascading is when you have 2 entities, and you want both of them to be UPDATE
ed / INSERT
ed / whatever even though you did something only to one of them explicitly. Your question doesn’t really relate to cascading – because you want to INSERT one entity, but UPDATE another one.
Now, you put a mappedBy
on the Tenant.properties
. This means that Property
will be the owning entity – it’s responsible for saving the connection between these 2 entities.
It means that you need to retrieve Property
from DB and set Tenant
to it. Then when saving Property
you’ll get your Foreign Key filled.