I have spent a couple of days with a weird problem. There is a plethora of similar posts here in StackOverflow and I have check a lot of them but I was unable to find something similar with this. I have a Human
Parent class
import javax.persistence.*; import java.util.Date; @Entity(name = "Human") @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) public abstract class Human { @Id @Column(name = "human_id", nullable = false) @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; @JsonProperty("name") private String name; @JsonProperty("date_of_birth") private Date dateOfBirth; @Embedded @JsonProperty("authentication_credential") private AuthenticationCredentials authCred; // constructors + setter/getters }
A User
child class :
import javax.persistence.*; import java.util.Date; @Entity(name = "User") @Table(name = "end_user") public class User extends Human { @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) @JsonProperty("contact_numbers") private CollectionOfContactMethods contactNumbers; @JsonProperty("telephone") private String telephone; // constructors + setter/getters }
and also a CollectionOfContactMethods
with composition relationship with the User
.
import javax.persistence.*; import java.util.List; @Entity(name = "CollectionOfContactMethods") @Table(name = "collection_of_contact_methods") public class CollectionOfContactMethods { @Id @Column(name = "collection_id", nullable = false) @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "ext_human_id", referencedColumnName = "human_id") private User user; @JsonProperty("email") private String email; // constructors + setter/getters }
The plan, according to the ER diagram is this :
However, what I get at a database level is this :
I appreciate the time you spent. Thanks.
PS : Here is the UserController
@RestController @RequestMapping("api/v1/user/") public class UserController { @Autowired UserService userService; @GetMapping(value = "users") Iterable<User> list() { Iterable<User> retVal = userService.findAll(); return retVal; } @RequestMapping(value = "user", method = RequestMethod.POST) User create(@RequestBody User user) { return userService.save(user); } @RequestMapping(value = "user/{id}", method = RequestMethod.GET ) Optional<User> get(@PathVariable Long id) { return userService.findById(id); } }
and also UserService
:
import com.tsakirogf.schedu.model.human.User; import org.springframework.data.repository.CrudRepository; public interface UserService extends CrudRepository<User, Long> { }
Advertisement
Answer
Since you have a bi-directional relationship between User
and CollectionOfContactMethods
, the issue might be that CollectionOfContactMethods
user
is null when you try to create it, hence the null data in the database or the not-null property references a null or transient value : com.tsakirogf.schedu.model.CollectionOfContactMethods.user
error. Try the following:
@RequestMapping(value = "user", method = RequestMethod.POST) User create(@RequestBody User user) { CollectionOfContactMethods contactNumbers = user.getContactNumbers(); contactNumbers.setUser(user); user.setContactNumbers(contactNumbers); return userService.save(user); }