I have a Post entity and a User entity (User can create many posts/advertisements), i'm trying to add a watchlist functionality so that a user can select any post and it would be watchlisted (Allowing them to kind of save a post for future reference).
I created a new entity called WatchlistPost, which contains a reference to both the User and the Post entities, and I can save a watchlisted post but I'd like to only allow a user to watchlist a particular post once (atm a user can watchlist multiple posts even if the post is the same / has the same post id).
A user should be able to watchlist multiple Posts, but not the same post multiple times.
This is my Post Entity
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Post {
private long EXPIRATION_TIME_DAYS = 14;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "Required")
@Size(min=20, message = "Minimum of 20 characters")
@Size(max=100, message = "Maximum of 100 characters")
@Column(unique = true)
private String title;
@NotBlank(message = "Required")
@Size(min = 50, message = "Minimum of 50 characters")
@Size(max = 2000, message = "Maximum of 2000 characters")
@Column(length = 2000)
private String description;
// Removed other fields
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="user_id")
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
private User user;
}
My User Entity
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank(message = "Required")
private String fullName;
// Removed other fields
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "user", orphanRemoval = true)
@OnDelete(action = OnDeleteAction.CASCADE)
private List<Post> posts = new ArrayList<>();
}
Watchlist Post Entity
package com.carspot.app.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name="watchlist_post")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WatchlistPost {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
@JoinColumn(name = "post_id", referencedColumnName = "id")
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
@JoinColumn(name = "user_id", referencedColumnName = "id")
private User user;
}
Service method to add a Watchlist Post
@Override
public void addToWatchlist(Long postId, String emailAddress) {
User user = userRepository.findUserByEmailAddress(emailAddress);
// findPostById(id) - finds post by id, or throws Exception if post doesn't exist
Post post = findPostById(postId);
WatchlistPost watchlistPost = new WatchlistPost();
watchlistPost.setPost(post);
watchlistPost.setUser(user);
postWatchlistRepository.save(watchlistPost);
}
Controller method
@PostMapping("api/post/watchlist/{postId}")
public ResponseEntity<?> addToWatchList(@PathVariable Long postId, Principal principal) {
postService.addToWatchlist(postId, principal.getName());
return new ResponseEntity<>("Post added to watchlist", HttpStatus.OK);
}

