I am new to R2DBC and I have a fairly standard parent child relationship Person / Address and when attempting to save a person object with an address both the person and the address get saved but the Person ID is not getting saved to Address table.
I am using Postgres with Micronaut and R2DBC. The following is the code
Base Fields:
@Data
@Introspected
@Serdeable
@MappedEntity
public class BaseFields {
@GeneratedValue
@Id
private Long id;
private String note;
private String recordType;
Person:
@Data
@Introspected
@Serdeable
@MappedEntity
public class Person extends BaseFields{
private String firstName;
private String lastName;
private String phoneNumber;
@JoinColumn(name = "personId")
@Relation(value = Relation.Kind.ONE_TO_MANY, cascade = Relation.Cascade.ALL)
private Set<Address> addresses;
}
Address:
@Data
@Introspected
@Serdeable
@MappedEntity
public class Address extends BaseFields {
private String street;
private String street2;
private String suite;
private String city;
private String stateProvince;
private String country;
private String postalCode;
private Boolean active;
private Long personId;
}
PersonRepository:
@Introspected
@R2dbcRepository(dialect = Dialect.POSTGRES)
public interface PersonRepository extends ReactiveStreamsCrudRepository<Person, Long>{
@NonNull
@Override
@Join(value = "addresses", type = Join.Type.FETCH)
Flux<Person> findAll();
@NonNull
@Override
@Join(value = "addresses", type = Join.Type.FETCH)
Mono<Person> findById(@NonNull @NotNull Long id);
}
PersonController:
@Controller("/person")
public class PersonController {
private final PersonRepository personRepository;
private final PersonService personService;
PersonController(PersonRepository personRepository, PersonService personService) {
this.personRepository = personRepository;
this.personService = personService;
@SingleResult
@Post
Mono<Person> create(@Valid @Body Person person){
// return personService.createPerson(person);
return Mono.from(personRepository.save(person));
}
}
Postman Body and result:
{
"firstName": "Kelly",
"lastName": "Kingster",
"phoneNumber": "451.881.9745",
"addresses": [
{
"street": "155379 W12th Street",
"city": "Fargo",
"stateProvince": "ND",
"country": "USA",
"postalCode": "44577",
"active": true
}
]
}
Result:
{
"id": 11,
"firstName": "Kelly",
"lastName": "Kingster",
"phoneNumber": "451.881.9745",
"addresses": [
{
"id": 12,
"street": "155379 W12th Street",
"city": "Fargo",
"stateProvince": "ND",
"country": "USA",
"postalCode": "44577",
"active": true
}
]
}
Both records are inserted but there is no person_id on the address record
"id","street","street2","suite","city","state_province","country","postal_code","active","person_id","record_type","note","created","modified"
12,"155379 W12th Street",NULL,NULL,"Fargo","ND","USA","44577",True,NULL,NULL,NULL,"2024-07-09 15:22:20.637259","2024-07-09 15:22:20.637259"
Try to update the annotation on your entities like this.
public class Person ...{
// ...
@Relation(value = Relation.Kind.ONE_TO_MANY, cascade = Relation.Cascade.ALL)
private Set<Address> addresses;
}
public class Address...{
@Relation(value = Relation.Kind.MANY_TO_ONE)
@JoinColumn("person_id") // move here
private Person person;
}
Check my Micronaut R2dbc example project here which demos one-to-many relations.
BTW: Micronaut Data supports JPA annotations in Micronaut data Jdbc/R2dbc, you can use JPA annotations directly if you are more familiar with it.