1

Here I'm doing a one to many mapping between user and notification tables. After executing the below code, my userId column in Notification table is empty. Is this the correct way to implementing the mapping?

User

@Entity
@Table(name = "users")
@Getter
@Setter
public class User {
    
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "userId")
   private int userId;
    
   @Column(name = "first_name")
   private String firstName;
    
   @Column(name = "last_name")
   private String lastName;
    
   @Column(name = "email")
   private String email;
    
   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true, mappedBy="user")
   private List<Notifications> notifications;
}

Notification

@Entity
@Table(name = "notifications")
@Getter
@Setter
public class Notifications {
    
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "notificationId")
   private int notificationId;
    
   @Column(name = "description")
   private String message;
    
   @Column(name = "is_read")
   private boolean isRead;
    
   @Column(name = "created_at")
   private Date createdAt;
    
   @ManyToOne(fetch = FetchType.EAGER)
   @JoinColumn(name="userId")
   private User user;
}

Saving the data,

@Autowired
UserRepo userRepository;
    
public String createNotification(int userId,Notifications notification) {
   User user = userRepository
         .findById(userId)
         .orElseThrow(() -> new ResourceNotFoundException("User not found with id: "+userId));
   user.getNotifications().add(notification);
   this.userRepository.save(user);
   return "Notification added to user successfully";
}

NOtification Object:

{
   "message":"abc",
   "isRead":"true",
   "createdAt:"2010-06-05"
}
SternK
  • 11,649
  • 22
  • 32
  • 46

2 Answers2

1

As it stated in the 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 createNotification method in the following way:

public String createNotification(int userId,Notifications notification){
   User user=userRepository
             .findById(userId)
             .orElseThrow(() -> new ResourceNotFoundException("User not found with id: "+userId));
   
   // sync both side of the association
   user.getNotifications().add(notification);
   notification.setUser(user);

   this.userRepository.save(user);
   return "Notification added to user successfully";
}
SternK
  • 11,649
  • 22
  • 32
  • 46
0

Although @SternK's answer is correct, I wanna suggest to keep the entities synchronized in the parent entity. e.g.

public class User {
...
public void addNotification(Notification n) {

notifications.add(n);
n.setUser(this);
}

Doing this, you do not be worry about keeping the entities synced while you are updating/inserting entities.

Morteza
  • 642
  • 7
  • 17