Issue
Here I m having two different tables, User and Profile Image. Both are mapped using One to One relation. The problem is- Foreign key of Profile Image (user_userid) is null when a new profile image is inserted into the database. Why is the user_id remains null... I come up with this issue many time.... Is there any issue with the way I m mapping both the entities?...
User
@Entity
@Getter
@Setter
@Table(name = "Users")
public class User {
@Id
@Column(name = "user_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToOne(cascade = CascadeType.ALL,mappedBy = "user",fetch =FetchType.LAZY)
private UserProfileImage userProfileImage;
}
Profile Image
@Entity
@Getter
@Setter
public class UserProfileImage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
@Column(name = "type")
private String type;
@Column(name = "picByte", length = 1000000)
private byte[] picByte;
@OneToOne(fetch =FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
public UserProfileImage() {
super();
}
public UserProfileImage(String name, String type, byte[] picByte) {
this.name = name;
this.type = type;
this.picByte = picByte;
}
}
Controller
public ResponseEntity<String> addProfileImage(int id,MultipartFile file) {
User user=userRepository.findById(id);
UserProfileImage present=user.getUserProfileImage();
if(present==null) {
UserProfileImage userProfileImage = new UserProfileImage(file.getOriginalFilename(), file.getContentType(), file.getBytes());
user.setUserProfileImage(userProfileImage);
}else{
present.setName(file.getOriginalFilename());
present.setType(file.getContentType());
present.setPicByte(file.getBytes());
user.setUserProfileImage(present);
}
userRepository.save(user);
}
Solution
As it's stated in the hibernate documentation:
Whenever a bidirectional association is formed, the application developer must make sure both sides are in-sync at all times.
So, you should correct your addProfileImage
method in this way:
public ResponseEntity<String> addProfileImage(int id,MultipartFile file) {
User user=userRepository.findById(id);
UserProfileImage present=user.getUserProfileImage();
if(present==null) {
UserProfileImage userProfileImage = new UserProfileImage(file.getOriginalFilename(), file.getContentType(), file.getBytes());
// sync both sides of bidirectional association
user.setUserProfileImage(userProfileImage);
userProfileImage.setUser(user);
} else {
present.setName(file.getOriginalFilename());
present.setType(file.getContentType());
present.setPicByte(file.getBytes());
// this is redundant
// user.setUserProfileImage(present);
}
userRepository.save(user);
}
Answered By - SternK
Answer Checked By - Mary Flores (JavaFixing Volunteer)