I am trying to implement bidirectional one to many relationship using Spring Data JPA. I have created test cases for save and get data and there is no issue in the mapping and data is getting saved in both the tables. But when I am trying to create data by hitting the Post request, foreign key is not getting saved. Mapping between Customer and Phone is bidirectional one to many.
OneToMany1Application
package com.jwt.onetomany;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OneToMany1Application {
public static void main(String[] args) {
SpringApplication.run(OneToMany1Application.class, args);
}
}
DemoController
package com.jwt.onetomany.controller;
import java.net.URI;
import java.util.List;
import org.apache.tomcat.jni.Poll;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.jwt.onetomany.entity.Customer;
import com.jwt.onetomany.repo.CustomerRepository;
@RestController
public class DemoController {
@Autowired
CustomerRepository customerRepository;
@GetMapping("/getall")
ResponseEntity<List<Customer>> getAllCustomers() {
Iterable<Customer> findAll = customerRepository.findAll();
List<Customer> customers = (List<Customer>) findAll;
return new ResponseEntity<List<Customer>>(customers, HttpStatus.OK);
}
@PostMapping(path = "/customers", produces = MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<?> createPoll(@RequestBody Customer customer) {
customerRepository.save(customer);
// Set the location header for the newly created resource
HttpHeaders responseHeaders = new HttpHeaders();
URI newPollUri = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(customer.getId())
.toUri();
responseHeaders.setLocation(newPollUri);
return new ResponseEntity<>(null, responseHeaders, HttpStatus.CREATED);
}
}
Customer
package com.jwt.onetomany.entity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<PhoneNumber> phoneNumbers;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<PhoneNumber> getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(Set<PhoneNumber> phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
public void addPhoneNumber(PhoneNumber number) {
if (number != null) {
if (phoneNumbers == null) {
phoneNumbers = new HashSet<>();
}
number.setCustomer(this);
phoneNumbers.add(number);
}
}
}
PhoneNumber
package com.jwt.onetomany.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity
@Table(name="phone_number")
public class PhoneNumber {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String number;
private String type;
@ManyToOne
@JoinColumn(name = "customer_id")
@JsonIgnore
private Customer customer;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
CustomerRepository
package com.jwt.onetomany.repo;
import org.springframework.data.repository.CrudRepository;
import com.jwt.onetomany.entity.Customer;
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}
Database use is mysql:
SQL Script
-----------
CREATE TABLE `customer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
CREATE TABLE `phone_number` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(11) DEFAULT NULL,
`number` varchar(20) DEFAULT NULL,
`type` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK1j552es3t8oswmbjr0rw15ew6` (`customer_id`),
CONSTRAINT `FK1j552es3t8oswmbjr0rw15ew6` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`),
CONSTRAINT `phone_number_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;