Adding a watchlist functionality for JPA Entity

Viewed 32

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.

A user can watchlist 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;
}


MySQL DDL for Watchlist table Watchlist table DDL


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);
    }
0 Answers
Related