I want to save a new UserRegistration instance in my database using Spring Data JPA. In the database I have the tables "users" and "authorities". Every time I try to save the instance I get the error "Cannot add or update a child row: a foreign key constraint fails". This is because the table "authorities" holds a foreign key referencing "users". The error is caused because Hibernate first tries to store the authority instance, before inserting the UserRegistration instance:
Hibernate:
insert
into
users
(email, enabled, password, profilePicture, username)
values
(?, ?, ?, ?, ?)
Hibernate:
insert
into
authorities
(authority, username, userid)
values
(?, ?, ?)
UserRegistration.java:
package main.java.de.ostfalia.seprojekt.database.models;
import java.util.List;
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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import main.java.de.ostfalia.seprojekt.database.dto.UserRegistrationDTO;
@Entity
@Table(name = "users")
public class UserRegistration {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
@JsonIgnore
private String password;
@JsonIgnore
private boolean enabled;
private Integer profilePicture;
private String email;
@OneToOne(fetch = FetchType.LAZY, optional = false, mappedBy = "user", cascade = CascadeType.ALL)
private Authority authority;
@JsonManagedReference
@ManyToMany
@JoinTable(name = "userhasfavorite", joinColumns = @JoinColumn(name = "userid"), inverseJoinColumns = @JoinColumn(name = "channelid"))
private List<Channel> favorites;
public UserRegistration() {
}
public UserRegistration(UserRegistrationDTO dto) {
this.email = dto.getEmail();
this.username = dto.getUsername();
this.password = dto.getPassword();
this.enabled = dto.isEnabled();
this.profilePicture = dto.getProfilePicture();
this.authority = new Authority(id, username, dto.getRole(), this);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean getEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Integer getProfilePicture() {
return profilePicture;
}
public void setProfilePicture(Integer profilePicture) {
this.profilePicture = profilePicture;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Authority getAuthority() {
return authority;
}
public void setAuthority(Authority authority) {
this.authority = authority;
}
public List<Channel> getFavorites() {
return favorites;
}
public void setFavorites(List<Channel> favorites) {
this.favorites = favorites;
}
}
Authority.java:
package main.java.de.ostfalia.seprojekt.database.models;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "authorities")
public class Authority {
@Id
@Column(name = "userid")
private int userID;
private String username;
private String authority;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userid")
private UserRegistration user;
public Authority() {
}
public Authority(int userID, String username, String authority, UserRegistration user) {
this.userID = userID;
this.username = username;
this.authority = authority;
this.user = user;
}
public int getUserID() {
return userID;
}
public void setUserID(int userID) {
this.userID = userID;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
}
Code that saves the entity:
@PostMapping
public boolean saveUser(@RequestBody UserRegistrationDTO userToSave) {
if (roleExists(userToSave.getRole())) {
UserRegistration user = new UserRegistration(userToSave);
uRepo.saveAndFlush(user);
return true;
}
return false;
}
My question now is: How can I save the UserRegistration instance, before inserting the authority instance using CascadeTypes?
Thank you for reading this question. I'm looking forward to get this problem fixed.
Aucun commentaire:
Enregistrer un commentaire