Index: Sources/src/main/java/com/wediscussmovies/project/LoggedUser.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/LoggedUser.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/LoggedUser.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,21 @@
+package com.wediscussmovies.project;
+
+import com.wediscussmovies.project.model.User;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+public class LoggedUser {
+
+    static  public User getLoggedUser(){
+
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+        if (!(auth instanceof AnonymousAuthenticationToken)) {
+            UserDetails userDetails = (UserDetails) auth.getPrincipal();
+            return (User) userDetails;
+        }
+        return null;
+    }
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/WeDiscussMoviesApplication.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/WeDiscussMoviesApplication.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/WeDiscussMoviesApplication.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,23 @@
+package com.wediscussmovies.project;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@SpringBootApplication
+public class WeDiscussMoviesApplication {
+
+    public static void main(String[] args) {
+
+        SpringApplication.run(WeDiscussMoviesApplication.class, args);
+    }
+    @Bean
+    PasswordEncoder getPasswordEncoder(){
+        return new BCryptPasswordEncoder(10);
+    }
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/ajaxmodels/Grade.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/ajaxmodels/Grade.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/ajaxmodels/Grade.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,14 @@
+package com.wediscussmovies.project.ajaxmodels;
+
+import lombok.Data;
+
+@Data
+public class Grade {
+    private Integer rating;
+    private String reason;
+
+    public Grade(String rating, String reason) {
+        this.rating = Integer.parseInt(rating);
+        this.reason = reason;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/configuration/CustomUsernamePasswordAuthenticationProvider.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/configuration/CustomUsernamePasswordAuthenticationProvider.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/configuration/CustomUsernamePasswordAuthenticationProvider.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,48 @@
+package com.wediscussmovies.project.configuration;
+
+import com.wediscussmovies.project.service.UserService;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.BadCredentialsException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Component;
+
+import javax.naming.AuthenticationException;
+
+@Component
+public class CustomUsernamePasswordAuthenticationProvider implements AuthenticationProvider {
+
+    private final UserService userService;
+    private final PasswordEncoder passwordEncoder;
+
+    public CustomUsernamePasswordAuthenticationProvider(UserService userService, PasswordEncoder passwordEncoder) {
+        this.userService = userService;
+        this.passwordEncoder = passwordEncoder;
+    }
+
+    @Override
+    public Authentication authenticate(Authentication authentication){
+        String username = authentication.getName();
+        String password = authentication.getCredentials().toString();
+
+        if ("".equals(username) || "".equals(password)) {
+            throw new BadCredentialsException("Invalid Credentials");
+        }
+
+        UserDetails userDetails = this.userService.loadUserByUsername(username);
+
+        if (!passwordEncoder.matches(password, userDetails.getPassword())) {
+            throw new BadCredentialsException("Password is incorrect!");
+        }
+        return new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
+
+    }
+
+    @Override
+    public boolean supports(Class<?> aClass) {
+        return aClass.equals(UsernamePasswordAuthenticationToken.class);
+    }
+}
+
Index: Sources/src/main/java/com/wediscussmovies/project/configuration/SecurityConfig.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/configuration/SecurityConfig.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/configuration/SecurityConfig.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,54 @@
+package com.wediscussmovies.project.configuration;
+
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+
+@Configuration
+public class SecurityConfig extends WebSecurityConfigurerAdapter {
+    private final CustomUsernamePasswordAuthenticationProvider authenticationProvider;
+
+    public SecurityConfig(CustomUsernamePasswordAuthenticationProvider authenticationProvider) {
+        this.authenticationProvider = authenticationProvider;
+    }
+
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        web.ignoring().antMatchers("/*.jpg");
+        web.ignoring().antMatchers("/*.png");
+        web.ignoring().antMatchers("/*.css");
+        web.ignoring().antMatchers("/*.js");
+    }
+
+    @Override
+    public void configure(HttpSecurity http) throws Exception {
+        // TODO: If you are implementing the security requirements, remove this following line
+        http.csrf().disable()
+                .authorizeRequests()
+                .antMatchers("/movies","/movies/**/","/actors","/persons/**/","/directors","/discussions","/profiles/**","/discussions/**/","/discussions/all/**/","/replies","/register","/genres", "/css/**","/img/**", "/js/**").permitAll()
+                .anyRequest()
+                .authenticated()
+                .and()
+                .formLogin()
+                .loginPage("/login")
+                .permitAll()
+                .failureUrl("/login?error=BadCredentials")
+                .defaultSuccessUrl("/movies", true)
+                .and()
+                .logout()
+                .logoutUrl("/logout")
+                .clearAuthentication(true)
+                .invalidateHttpSession(true)
+                .deleteCookies("JSESSIONID")
+                .logoutSuccessUrl("/movies");
+
+    }
+
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        auth.authenticationProvider(authenticationProvider);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/Discussion.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/Discussion.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/Discussion.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,77 @@
+package com.wediscussmovies.project.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+
+import javax.persistence.*;
+import java.time.LocalDate;
+import java.util.Objects;
+
+@Entity
+@Table(name = "discussions", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class Discussion {
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Id
+    @Column(name = "discussion_id")
+    private int discussionId;
+    @Basic
+    @Column(name = "type")
+    private Character type;
+    @Basic
+    @Column(name = "text")
+    private String text;
+    @Basic
+    @Column(name = "title")
+    private String title;
+    @Basic
+    @Column(name = "date")
+    private LocalDate date;
+
+
+
+
+
+    @ManyToOne
+    @JoinColumn(name = "movie_id")
+    private Movie movie;
+
+    @ManyToOne
+    @JoinColumn(name = "user_id")
+    private User user;
+
+    @ManyToOne
+    @JoinColumn(name = "person_id")
+    private Person person;
+
+    @Transient
+    private long likes;
+
+    public Discussion(Character type, String text, String title, LocalDate date, User user) {
+        this.type = type;
+        this.text = text;
+        this.title = title;
+        this.date = date;
+        this.user = user;
+    }
+
+
+
+    public Discussion() {
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Discussion that = (Discussion) o;
+        return discussionId == that.discussionId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(discussionId);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/Genre.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/Genre.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/Genre.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,45 @@
+package com.wediscussmovies.project.model;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Objects;
+
+@Entity
+@Table(name = "genres", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class Genre {
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Id
+    @Column(name = "genre_id")
+    private int genreId;
+    @Basic
+    @Column(name = "genre_type")
+    private String genreType;
+
+    public Genre() {
+
+    }
+
+    public Genre(int genreId, String genreType) {
+        this.genreId = genreId;
+        this.genreType = genreType;
+    }
+
+    public Genre(String genreType) {
+        this.genreType = genreType;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Genre genre = (Genre) o;
+        return genreId == genre.genreId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(genreId);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/Movie.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/Movie.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/Movie.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,110 @@
+package com.wediscussmovies.project.model;
+
+import com.wediscussmovies.project.model.relation.MovieLikes;
+import com.wediscussmovies.project.model.relation.MovieActors;
+import com.wediscussmovies.project.model.relation.MovieGenres;
+import com.wediscussmovies.project.model.relation.MovieRates;
+import lombok.Data;
+import org.hibernate.annotations.Fetch;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.sql.Date;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Objects;
+
+@Entity
+@Table(name = "movies", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class Movie {
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Id
+    @Column(name = "movie_id")
+    private int movieId;
+    @Basic
+    @Column(name = "title")
+    private String title;
+    @Basic
+    @Column(name = "description")
+    private String description;
+    @Basic
+    @Column(name = "image_url")
+    private String imageUrl;
+    @Basic
+    @Column(name = "airing_date")
+    private Date airingDate;
+    @Basic
+    @Column(name = "imdb_rating")
+    private Double imdbRating;
+
+    @OneToMany(mappedBy = "movie", fetch = FetchType.LAZY)
+    private Collection<MovieActors> actors;
+    @OneToMany(mappedBy = "movie", fetch = FetchType.LAZY)
+    private Collection<MovieGenres> genres;
+    @OneToMany(mappedBy = "movie")
+    private Collection<MovieLikes> likes;
+    @OneToMany(mappedBy = "movie")
+    private Collection<MovieRates> rates;
+
+    @ManyToOne
+    @JoinColumn(name = "director_id")
+    private Person director;
+
+    public Movie() {
+
+    }
+
+    public Movie(String title, String description, String imageUrl, Date airingDate,
+                 Double imdbRating, Person director) {
+        this.title = title;
+        this.description = description;
+        this.imageUrl = imageUrl;
+        this.airingDate = airingDate;
+        this.imdbRating = imdbRating;
+        this.director = director;
+
+    }
+
+    public Movie(int movieId, String title, Double imdbRating, String imageUrl) {
+        this.movieId = movieId;
+        this.title = title;
+        this.imdbRating = imdbRating;
+        this.imageUrl = imageUrl;
+    }
+
+    public String getDateFormatted(){
+        String dob = airingDate.toString();
+        String [] parts = dob.split("-");
+        return parts[2]+"/"+parts[1]+"/"+parts[0];
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Movie movie = (Movie) o;
+        return movieId == movie.movieId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(movieId);
+    }
+
+    public static Comparator<Movie> comparatorTitle = Comparator.comparing(Movie::getTitle);
+
+
+    public String getShortTitle(){
+        int to = 20;
+        if (title.length() < to)
+            to = title.length();
+        if(to<20)
+            return title;
+        return title.substring(0, to) + "...";
+    }
+
+
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/PasswordEncoder.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/PasswordEncoder.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/PasswordEncoder.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,36 @@
+package com.wediscussmovies.project.model;
+
+
+import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class PasswordEncoder {
+    public static byte[] getSHA(String input) throws NoSuchAlgorithmException
+    {
+        MessageDigest md = MessageDigest.getInstance("SHA-512");
+
+        return md.digest(input.getBytes(StandardCharsets.UTF_8));
+    }
+
+    public static String toHexString(byte[] hash)
+    {
+        BigInteger number = new BigInteger(1, hash);
+
+        StringBuilder hexString = new StringBuilder(number.toString(16));
+
+        while (hexString.length() < 32)
+        {
+            hexString.insert(0, '0');
+        }
+
+        return hexString.toString();
+    }
+
+    public static String getEncodedPasswordString(String password) throws NoSuchAlgorithmException {
+        return toHexString(getSHA(password));
+    }
+
+}
+
Index: Sources/src/main/java/com/wediscussmovies/project/model/Person.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/Person.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/Person.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,103 @@
+package com.wediscussmovies.project.model;
+
+import com.wediscussmovies.project.model.relation.MovieActors;
+import com.wediscussmovies.project.model.relation.PersonRates;
+import lombok.Data;
+
+import javax.persistence.*;
+import javax.swing.text.DateFormatter;
+import java.io.Serializable;
+import java.sql.Date;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Collection;
+
+@Entity
+@Table(name = "persons", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class Person {
+
+    /*
+    ni fale tabela za person koj zanrovi gi ima - ako e potrebno
+     */
+
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Id
+    @Column(name = "person_id")
+    private int personId;
+    @Basic
+    @Column(name = "name")
+    private String name;
+    @Basic
+    @Column(name = "surname")
+    private String surname;
+    @Basic
+    @Column(name = "type")
+    private Character type;
+    @Basic
+    @Column(name = "date_of_birth")
+    private Date dateOfBirth;
+    @Basic
+    @Column(name = "image_url")
+    private String imageUrl;
+    @Basic
+    @Column(name = "description")
+    private String description;
+    @OneToMany(mappedBy = "person")
+    private Collection<Discussion> discussions;
+    @OneToMany(mappedBy = "person")
+    private Collection<MovieActors> movieActors;
+    @OneToMany(mappedBy = "director")
+    private Collection<Movie> movies;
+    @OneToMany(mappedBy = "person")
+    private Collection<PersonRates> personRates;
+
+
+
+    public Person() {
+
+    }
+
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Person that = (Person) o;
+
+        return personId == that.getPersonId();
+    }
+
+    @Override
+    public int hashCode() {
+
+        return personId * 31;
+    }
+
+
+    public String getDateFormatted(){
+        String dob = dateOfBirth.toString();
+        String [] parts = dob.split("-");
+        return parts[2]+"/"+parts[1]+"/"+parts[0];
+    }
+
+
+    public Person(String name, String surname, Character type, Date dateOfBirth, String imageUrl, String description) {
+        this.name = name;
+        this.surname = surname;
+        this.type = type;
+        this.dateOfBirth = dateOfBirth;
+        this.imageUrl = imageUrl;
+        this.description = description;
+    }
+
+    public boolean hasGradeFromUser(User user){
+        for(PersonRates p: personRates){
+            if(p.getUser().getUserId() == user.getUserId())
+                return true;
+        }
+        return false;
+    }
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/Reply.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/Reply.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/Reply.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,57 @@
+package com.wediscussmovies.project.model;
+
+import com.wediscussmovies.project.model.primarykeys.ReplyPK;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.sql.Date;
+import java.util.Objects;
+
+@Entity
+@Table(name = "replies", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+@IdClass(ReplyPK.class)
+public class Reply implements Serializable {
+
+    @Column(name = "discussion_id")
+    @Id
+    private int discussionId;
+
+    @Column(name = "reply_id")
+    @Id
+    private int replyId;
+
+    @Basic
+    @Column(name = "text")
+    private String text;
+
+    @Basic
+    @Column(name = "date")
+    private Date date;
+
+
+
+    @ManyToOne
+    @MapsId("discussion_id")
+    @JoinColumn(name = "discussion_id")
+    private Discussion discussion;
+
+
+    @ManyToOne
+    @JoinColumn(name = "user_id")
+    private User user;
+
+    public Reply() {
+    }
+
+    public Reply(Discussion discussion, String text, Date date, User user) {
+        this.discussion = discussion;
+        this.discussionId = discussion.getDiscussionId();
+        this.text = text;
+        this.date = date;
+        this.user = user;
+    }
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/User.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/User.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/User.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,105 @@
+package com.wediscussmovies.project.model;
+
+import com.wediscussmovies.project.model.relation.MovieLikes;
+import com.wediscussmovies.project.model.relation.UserGenres;
+import com.wediscussmovies.project.model.relation.MovieRates;
+import com.wediscussmovies.project.model.relation.PersonRates;
+import lombok.Data;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Objects;
+
+@Entity
+@Table(name = "users", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class User implements UserDetails {
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Id
+    @Column(name = "user_id")
+    private int userId;
+    @Basic
+    @Column(name = "username")
+    private String username;
+    @Basic
+    @Column(name = "name")
+    private String name;
+    @Basic
+    @Column(name = "surname")
+    private String surname;
+    @Basic
+    @Column(name = "email")
+    private String email;
+    @Basic
+    @Column(name = "password")
+    private String password;
+    @OneToMany(mappedBy = "user")
+    private Collection<Discussion> discussions;
+    @OneToMany(mappedBy = "user")
+    private Collection<MovieLikes> movieLikes;
+    @OneToMany(mappedBy = "user")
+    private Collection<MovieRates> movieRates;
+    @OneToMany(mappedBy = "user")
+    private Collection<PersonRates> personRates;
+    @OneToMany(mappedBy = "user")
+    private Collection<Reply> replies;
+    @OneToMany(mappedBy = "user")
+    private Collection<UserGenres> userGenres;
+
+    public User() {
+
+    }
+
+
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return true;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return true;
+    }
+
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        return new ArrayList<>();
+    }
+
+    public User( String email,String username , String password, String name,String surname)  {
+        this.username = username;
+        this.name = name;
+        this.surname = surname;
+        this.email = email;
+        this.password = password;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        User user = (User) o;
+        return userId == user.userId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(userId);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/enumerations/DiscussionType.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/enumerations/DiscussionType.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/enumerations/DiscussionType.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,5 @@
+package com.wediscussmovies.project.model.enumerations;
+
+public enum DiscussionType {
+    M,P
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/enumerations/PersonType.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/enumerations/PersonType.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/enumerations/PersonType.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,5 @@
+package com.wediscussmovies.project.model.enumerations;
+
+public enum PersonType {
+    A, D
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/DiscussionNotExistException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/DiscussionNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/DiscussionNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class DiscussionNotExistException extends RuntimeException{
+    public DiscussionNotExistException(Integer id){
+        super("Дискусијата со број " + id +" не постои!");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/GenreNotExistException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/GenreNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/GenreNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class GenreNotExistException extends RuntimeException {
+    public GenreNotExistException(Integer id){
+        super("Жанрот со дадениот идентификатор " + id + " не постои!");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/InvalidArgumentsException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/InvalidArgumentsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/InvalidArgumentsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class InvalidArgumentsException extends RuntimeException{
+    public InvalidArgumentsException(){
+        super("Невалидна најава!");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/InvalidUserCredentialsException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/InvalidUserCredentialsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/InvalidUserCredentialsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class InvalidUserCredentialsException extends RuntimeException{
+    public InvalidUserCredentialsException(String username) {
+        super("The user with the username {" + username +"} cannot be authenticated.");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/MovieHasAlreadyDirector.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/MovieHasAlreadyDirector.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/MovieHasAlreadyDirector.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,8 @@
+package com.wediscussmovies.project.model.exception;
+
+public class MovieHasAlreadyDirector extends RuntimeException{
+
+    public MovieHasAlreadyDirector(String title,String name, String surname){
+        super("За режисер на филмот " + title + " е поставен " + name + " " + surname);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/MovieIdNotFoundException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/MovieIdNotFoundException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/MovieIdNotFoundException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class MovieIdNotFoundException extends RuntimeException{
+    public MovieIdNotFoundException(Integer id) {
+        super("Movie with id {"+id+"} was not found.");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/NotEnoughArgumentsException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/NotEnoughArgumentsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/NotEnoughArgumentsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,4 @@
+package com.wediscussmovies.project.model.exception;
+
+public class NotEnoughArgumentsException {
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/PasswordsDoNotMatchException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/PasswordsDoNotMatchException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/PasswordsDoNotMatchException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class PasswordsDoNotMatchException extends RuntimeException{
+    public PasswordsDoNotMatchException(){
+        super("Лозинките не се совпаѓаат!");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/PasswordsDontMatchException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/PasswordsDontMatchException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/PasswordsDontMatchException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class PasswordsDontMatchException extends RuntimeException{
+    public PasswordsDontMatchException() {
+        super("The passwords you provided did not match.");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/PersonNotExistException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/PersonNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/PersonNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class PersonNotExistException extends RuntimeException{
+    public PersonNotExistException(Integer id){
+        super("Личност со број " + id + " не постои!");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/ReplyNotExistException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/ReplyNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/ReplyNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,9 @@
+package com.wediscussmovies.project.model.exception;
+
+import com.wediscussmovies.project.model.primarykeys.ReplyPK;
+
+public class ReplyNotExistException extends RuntimeException{
+    public ReplyNotExistException(ReplyPK id){
+        super("Репликата со број " + id + " не постои!");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/UserNotExistException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/UserNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/UserNotExistException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class UserNotExistException extends RuntimeException{
+    public UserNotExistException(String username){
+        super("Корисник со корисничко име " + username + " не постои!");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/UserWithEmailAlreadyExists.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/UserWithEmailAlreadyExists.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/UserWithEmailAlreadyExists.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class UserWithEmailAlreadyExists extends RuntimeException{
+    public UserWithEmailAlreadyExists(String email) {
+        super("User with the email {" + email +"} is already registered");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/UserWithUsernameAlreadyExists.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/UserWithUsernameAlreadyExists.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/UserWithUsernameAlreadyExists.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class UserWithUsernameAlreadyExists extends RuntimeException{
+    public UserWithUsernameAlreadyExists(String username) {
+        super("User with the username " + username + " is already registered");
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/exception/UsernameAlreadyExistsException.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/exception/UsernameAlreadyExistsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/exception/UsernameAlreadyExistsException.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.model.exception;
+
+public class UsernameAlreadyExistsException extends RuntimeException{
+    public UsernameAlreadyExistsException(String username){
+        super("Корисничкото име е зафатено " + username);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/DiscussionLikesPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/DiscussionLikesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/DiscussionLikesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,40 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import java.io.Serializable;
+import java.util.Objects;
+
+@Embeddable
+@Data
+public class DiscussionLikesPK implements Serializable {
+    @Column(name = "discussion_id")
+    private int discussionId;
+
+    @Column(name = "user_id")
+    private int userId;
+
+    public DiscussionLikesPK(int discussionId, int userId) {
+        this.discussionId = discussionId;
+        this.userId = userId;
+    }
+
+    public DiscussionLikesPK() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DiscussionLikesPK that = (DiscussionLikesPK) o;
+        return discussionId == that.discussionId && userId == that.userId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(discussionId, userId);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/GenreLikesPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/GenreLikesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/GenreLikesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,43 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import java.io.Serializable;
+
+@Embeddable
+@Data
+public class GenreLikesPK implements Serializable {
+
+    @Column(name = "genre_id")
+    private int genreId;
+
+    @Column(name = "user_id")
+    private int userId;
+
+    public GenreLikesPK() {
+    }
+
+    public GenreLikesPK(int genreId, int userId) {
+        this.genreId = genreId;
+        this.userId = userId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        GenreLikesPK that = (GenreLikesPK) o;
+
+        return userId == that.userId && genreId == that.genreId;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = genreId;
+        result = 31 * result + userId;
+        return result;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieActorsPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieActorsPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieActorsPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,43 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.io.Serializable;
+
+
+@Data
+@Embeddable
+public class MovieActorsPK implements Serializable {
+
+    @Column(name = "movie_id")
+    private int movieId;
+
+    @Column(name = "actor_id")
+    private int actorId;
+
+    public MovieActorsPK(int movieId, int actorId) {
+        this.movieId = movieId;
+        this.actorId = actorId;
+    }
+
+    public MovieActorsPK() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MovieActorsPK that = (MovieActorsPK) o;
+
+        return actorId == that.actorId && movieId == that.movieId;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = movieId;
+        result = 31 * result + actorId;
+        return result;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieGenresPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieGenresPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieGenresPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,44 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+@Embeddable
+@Data
+public class MovieGenresPK implements Serializable {
+
+    @Column(name = "movie_id")
+    private int movieId;
+
+    @Column(name = "genre_id")
+    private int genreId;
+
+    public MovieGenresPK(int movieId, int genreId) {
+        this.movieId = movieId;
+        this.genreId = genreId;
+    }
+
+    public MovieGenresPK() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MovieGenresPK that = (MovieGenresPK) o;
+
+        return genreId == that.genreId && movieId == that.movieId;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = movieId;
+        result = 31 * result + genreId;
+        return result;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieLikesPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieLikesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieLikesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,44 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+@Embeddable
+@Data
+public class MovieLikesPK implements Serializable {
+
+    @Column(name = "movie_id")
+    private int movieId;
+
+    @Column(name = "user_id")
+    private int userId;
+
+    public MovieLikesPK() {
+    }
+
+    public MovieLikesPK(int movieId, int userId) {
+        this.movieId = movieId;
+        this.userId = userId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MovieLikesPK that = (MovieLikesPK) o;
+
+        return userId == that.userId && movieId == that.movieId;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = movieId;
+        result = 31 * result + userId;
+        return result;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieRatesPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieRatesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/MovieRatesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,47 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+@Embeddable
+@Data
+public class MovieRatesPK implements Serializable {
+
+    @Column(name = "movie_id")
+    private int movieId;
+
+    @Column(name = "user_id")
+    private int userId;
+
+
+    public MovieRatesPK() {
+    }
+
+    public MovieRatesPK(int movieId, int userId) {
+        this.movieId = movieId;
+        this.userId = userId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MovieRatesPK that = (MovieRatesPK) o;
+
+
+
+        return movieId == that.movieId && userId == that.userId;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = movieId;
+        result = 31 * result + userId;
+        return result;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/PersonRatesPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/PersonRatesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/PersonRatesPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,45 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+@Embeddable
+@Data
+public class PersonRatesPK implements Serializable {
+
+    @Column(name = "person_id")
+    private int personId;
+
+    @Column(name = "user_id")
+    private int userId;
+
+    public PersonRatesPK() {
+    }
+
+    public PersonRatesPK(int personId, int userId) {
+        this.personId = personId;
+        this.userId = userId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PersonRatesPK that = (PersonRatesPK) o;
+
+
+        return personId == that.personId && userId == that.userId;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = personId;
+        result = 31 * result + userId;
+        return result;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/ReplyPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/ReplyPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/ReplyPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,45 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Objects;
+
+@Data
+public class ReplyPK implements Serializable {
+
+    @Column(name = "discussion_id")
+    private int discussionId;
+
+    @Column(name = "reply_id")
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int replyId;
+
+    public ReplyPK(int discussionId) {
+        this.discussionId = discussionId;
+    }
+
+    public ReplyPK(int discussionId, int replyId) {
+        this.discussionId = discussionId;
+        this.replyId = replyId;
+    }
+
+    public ReplyPK() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ReplyPK replyPK = (ReplyPK) o;
+        return discussionId == replyPK.discussionId && replyId == replyPK.replyId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(discussionId, replyId);
+    }
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/UserGenresPK.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/UserGenresPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/primarykeys/UserGenresPK.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,44 @@
+package com.wediscussmovies.project.model.primarykeys;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+@Data
+@Embeddable
+public class UserGenresPK implements Serializable {
+
+    @Column(name = "user_id")
+    private int userId;
+
+    @Column(name = "genre_id")
+    private int genreId;
+
+    public UserGenresPK() {
+    }
+
+    public UserGenresPK(int userId, int genreId) {
+        this.userId = userId;
+        this.genreId = genreId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        UserGenresPK that = (UserGenresPK) o;
+
+        return userId == that.userId && genreId == that.genreId;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = userId;
+        result = 31 * result + genreId;
+        return result;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/relation/DiscussionLikes.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/relation/DiscussionLikes.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/relation/DiscussionLikes.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,39 @@
+package com.wediscussmovies.project.model.relation;
+
+
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.DiscussionLikesPK;
+import com.wediscussmovies.project.model.primarykeys.MovieLikesPK;
+import lombok.Data;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "discussion_likes", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class DiscussionLikes {
+    @EmbeddedId
+    private DiscussionLikesPK id;
+
+    @ManyToOne
+    @MapsId("discussion_id")
+    @JoinColumn(name = "discussion_id")
+    private Discussion discussion;
+
+
+    @ManyToOne
+    @MapsId("user_id")
+    @JoinColumn(name = "user_id")
+    private User user;
+
+    public DiscussionLikes(Discussion discussion, User user) {
+        this.id = new DiscussionLikesPK(discussion.getDiscussionId(), user.getUserId());
+        this.discussion = discussion;
+        this.user = user;
+    }
+
+    public DiscussionLikes() {
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieActors.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieActors.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieActors.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,52 @@
+package com.wediscussmovies.project.model.relation;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.primarykeys.MovieActorsPK;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Objects;
+
+@Entity
+@Table(name = "movie_actors", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class MovieActors {
+
+    @EmbeddedId
+    private MovieActorsPK id;
+
+
+    @ManyToOne
+    @MapsId("movie_id")
+    @JoinColumn(name = "movie_id")
+    private Movie movie;
+
+
+    @ManyToOne
+    @MapsId("actor_id")
+    @JoinColumn(name = "actor_id")
+    private Person person;
+
+    public MovieActors(Movie movie, Person person) {
+        this.id = new MovieActorsPK(movie.getMovieId(),person.getPersonId());
+        this.movie = movie;
+        this.person = person;
+    }
+
+    public MovieActors() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        MovieActors that = (MovieActors) o;
+        return Objects.equals(id, that.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieGenres.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieGenres.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieGenres.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,41 @@
+package com.wediscussmovies.project.model.relation;
+
+import com.wediscussmovies.project.model.Genre;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.primarykeys.MovieGenresPK;
+import lombok.Data;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "movie_genres", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class MovieGenres {
+
+    @EmbeddedId
+    private MovieGenresPK id;
+
+    @ManyToOne
+    @MapsId(value = "genre_id")
+    @JoinColumn(name = "genre_id")
+    private Genre genre;
+
+    @ManyToOne
+    @MapsId("movie_id")
+    @JoinColumn(name = "movie_id")
+    private Movie movie;
+
+    public MovieGenres() {
+    }
+
+    public MovieGenres(Movie movie, Genre genre) {
+        this.id = new MovieGenresPK(movie.getMovieId(),genre.getGenreId());
+        this.genre = genre;
+        this.movie = movie;
+    }
+
+
+
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieLikes.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieLikes.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieLikes.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,50 @@
+package com.wediscussmovies.project.model.relation;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.MovieLikesPK;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Objects;
+
+@Entity
+@Table(name = "movie_likes", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class MovieLikes {
+   @EmbeddedId
+   private MovieLikesPK id;
+
+    @ManyToOne
+    @MapsId("movie_id")
+    @JoinColumn(name = "movie_id")
+    private Movie movie;
+
+
+    @ManyToOne
+    @MapsId("user_id")
+    @JoinColumn(name = "user_id")
+    private User user;
+
+    public MovieLikes(Movie movie, User user) {
+        this.id = new MovieLikesPK(movie.getMovieId(), user.getUserId());
+        this.movie = movie;
+        this.user = user;
+    }
+
+    public MovieLikes() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        MovieLikes that = (MovieLikes) o;
+        return Objects.equals(id, that.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieRates.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieRates.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/relation/MovieRates.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,47 @@
+package com.wediscussmovies.project.model.relation;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.MovieRatesPK;
+import lombok.Data;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "movie_rates", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class MovieRates {
+
+    @EmbeddedId
+    private MovieRatesPK id;
+
+    @Basic
+    @Column(name = "reason")
+    private String reason;
+    @Basic
+    @Column(name = "stars_rated")
+    private int starsRated;
+
+
+    @ManyToOne
+    @MapsId("movie_id")
+    @JoinColumn(name = "movie_id")
+    private Movie movie;
+
+
+    @ManyToOne
+    @MapsId("user_id")
+    @JoinColumn(name = "user_id")
+    private User user;
+
+    public MovieRates() {
+    }
+
+    public MovieRates(User user,Movie movie,String reason,Integer starsRated) {
+        this.id = new MovieRatesPK(movie.getMovieId(), user.getUserId());
+        this.reason = reason;
+        this.starsRated = starsRated;
+        this.movie = movie;
+        this.user = user;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/relation/PersonRates.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/relation/PersonRates.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/relation/PersonRates.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,62 @@
+package com.wediscussmovies.project.model.relation;
+
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.PersonRatesPK;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Objects;
+
+@Entity
+@Table(name = "person_rates", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class PersonRates {
+
+    @EmbeddedId
+    private PersonRatesPK id;
+
+    @Basic
+    @Column(name = "reason")
+    private String reason;
+    @Basic
+    @Column(name = "stars_rated")
+    private int starsRated;
+
+
+    @ManyToOne
+    @JoinColumn(name = "person_id")
+    @MapsId("person_id")
+    private Person person;
+
+
+    @ManyToOne
+    @JoinColumn(name = "user_id")
+    @MapsId("user_id")
+    private User user;
+
+
+    public PersonRates() {
+    }
+
+    public PersonRates(User user, Person person, String reason, Integer starsRated) {
+        this.id = new PersonRatesPK(person.getPersonId(), user.getUserId());
+        this.reason = reason;
+        this.starsRated = starsRated;
+        this.person = person;
+        this.user = user;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PersonRates that = (PersonRates) o;
+        return Objects.equals(id, that.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/model/relation/UserGenres.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/model/relation/UserGenres.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/model/relation/UserGenres.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,50 @@
+package com.wediscussmovies.project.model.relation;
+
+import com.wediscussmovies.project.model.Genre;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.UserGenresPK;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.util.Objects;
+
+@Entity
+@Table(name = "user_genres", schema = "project", catalog = "db_202122z_va_prj_wediscussmovies")
+@Data
+public class UserGenres {
+
+    @EmbeddedId
+    private UserGenresPK id;
+
+    @ManyToOne
+    @MapsId("genre_id")
+    @JoinColumn(name = "genre_id")
+    private Genre genre;
+
+    @ManyToOne
+    @MapsId("user_id")
+    @JoinColumn(name = "user_id")
+    private User user;
+
+    public UserGenres() {
+    }
+
+    public UserGenres(Genre genre, User user) {
+        this.id = new UserGenresPK(user.getUserId(), genre.getGenreId());
+        this.genre = genre;
+        this.user = user;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        UserGenres that = (UserGenres) o;
+        return Objects.equals(id, that.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/querymodels/DiscussionLikesQM.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/querymodels/DiscussionLikesQM.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/querymodels/DiscussionLikesQM.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,34 @@
+package com.wediscussmovies.project.querymodels;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.User;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.Objects;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class DiscussionLikesQM {
+
+    private Integer discussionId;
+    private Long likes;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DiscussionLikesQM that = (DiscussionLikesQM) o;
+        return Objects.equals(discussionId, that.discussionId) && Objects.equals(likes, that.likes);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(discussionId, likes);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/querymodels/GenreLikesQM.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/querymodels/GenreLikesQM.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/querymodels/GenreLikesQM.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,34 @@
+package com.wediscussmovies.project.querymodels;
+
+import lombok.Data;
+
+import java.util.Objects;
+
+@Data
+public class GenreLikesQM {
+    private Integer genreId;
+    private String name;
+    private Long likes;
+
+    //public static Comparator<GenreLikes> sorter = Comparator.comparing(GenreLikes::getLikes).thenComparing(GenreLikes::getName).reversed();
+
+    public GenreLikesQM(Integer genreId, String name, Long likes) {
+        this.genreId = genreId;
+        this.name = name;
+        this.likes = likes;
+
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        GenreLikesQM that = (GenreLikesQM) o;
+        return Objects.equals(genreId, that.genreId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(genreId);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/querymodels/MovieLikesQM.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/querymodels/MovieLikesQM.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/querymodels/MovieLikesQM.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,29 @@
+package com.wediscussmovies.project.querymodels;
+
+import lombok.Data;
+
+import java.util.Objects;
+
+@Data
+public class MovieLikesQM {
+    private Integer movieId;
+    private Long likes;
+
+    public MovieLikesQM(Integer movieId, Long likes) {
+        this.movieId = movieId;
+        this.likes = likes;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        MovieLikesQM that = (MovieLikesQM) o;
+        return Objects.equals(movieId, that.movieId) && Objects.equals(likes, that.likes);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(movieId, likes);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/DiscussionLikesRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/DiscussionLikesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/DiscussionLikesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,19 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.DiscussionLikesPK;
+import com.wediscussmovies.project.model.primarykeys.UserGenresPK;
+import com.wediscussmovies.project.model.relation.DiscussionLikes;
+import com.wediscussmovies.project.model.relation.MovieLikes;
+import com.wediscussmovies.project.model.relation.UserGenres;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface DiscussionLikesRepository extends JpaRepository<DiscussionLikes, DiscussionLikesPK> {
+    List<DiscussionLikes> findAllByUser(User user);
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/DiscussionRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/DiscussionRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/DiscussionRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,35 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.querymodels.DiscussionLikesQM;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+@Repository
+public interface DiscussionRepository extends JpaRepository<Discussion, Integer> {
+     List<Discussion> findAllByTitleLike(String title);
+     List<Discussion> findAllByMovie(Movie movie);
+     List<Discussion> findAllByPerson (Person person);
+
+     @Query(value = "select new com.wediscussmovies.project.querymodels.DiscussionLikesQM(d.discussionId, count (dl.user) ) from Discussion d" +
+             " left join DiscussionLikes dl on dl.id.discussionId = d.discussionId" +
+             " where :id = d.discussionId" +
+             " group by d.discussionId")
+     @Transactional
+     DiscussionLikesQM findDiscussionWithLikes(@Param("id") Integer discussionId);
+
+     @Query(value = "select new com.wediscussmovies.project.querymodels.DiscussionLikesQM (d.discussionId, count(dl.user))  from Discussion d" +
+             " left join DiscussionLikes dl on dl.id.discussionId = d.discussionId" +
+             " group by d.discussionId"+
+               " order by d.discussionId asc")
+     @Transactional
+     List<DiscussionLikesQM
+             > findAllDiscussionsWithLikes();
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/GenreLikesRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/GenreLikesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/GenreLikesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,14 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.UserGenresPK;
+import com.wediscussmovies.project.model.relation.UserGenres;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface GenreLikesRepository  extends JpaRepository<UserGenres, UserGenresPK> {
+    List<UserGenres> findAllByUser(User user);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/GenreRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/GenreRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/GenreRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,33 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.Genre;
+import com.wediscussmovies.project.querymodels.GenreLikesQM;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+
+@Repository
+public interface GenreRepository extends JpaRepository<Genre, Integer> {
+     List<Genre> findAllByGenreType(String genre);
+
+     @Query(value = "select new com.wediscussmovies.project.querymodels.GenreLikesQM(g.genreId, g.genreType, count(ug.id.userId)) from Genre g" +
+             " left join UserGenres ug on ug.id.genreId = g.genreId" +
+             " group by g.genreId, g.genreType" +
+             " order by count(ug.id.userId) desc, g.genreType asc")
+     @Transactional
+     List<GenreLikesQM> findAllWithLikes();
+
+     @Modifying
+     @Query(value = "insert into project.user_genres (user_id,genre_id) values(:user_id,:genre_id)",nativeQuery = true)
+     @Transactional
+     void insertInto(@Param("user_id")Integer userId, @Param("genre_id")Integer genreId);
+
+     @Query(value = "select new com.wediscussmovies.project.model.Genre (g.genreId, g.genreType) from Genre g" +
+     " ORDER BY g.genreType DESC")
+     List<Genre> findAllSorted();
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/MovieActorsRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/MovieActorsRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/MovieActorsRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,19 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.relation.MovieActors;
+import com.wediscussmovies.project.model.primarykeys.MovieActorsPK;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface MovieActorsRepository extends JpaRepository<MovieActors, MovieActorsPK> {
+
+    List<MovieActors> deleteAllByMovie(Movie movie);
+    List<MovieActors> findAllByMovie(Movie movie);
+    List<MovieActors> findAllByPerson(Person person);
+    void deleteAllByPerson(Person person);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/MovieGenresRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/MovieGenresRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/MovieGenresRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,15 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.relation.MovieGenres;
+import com.wediscussmovies.project.model.primarykeys.MovieGenresPK;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface MovieGenresRepository extends JpaRepository<MovieGenres, MovieGenresPK> {
+    List<MovieGenres> deleteAllByMovie(Movie movie);
+    List<MovieGenres> findAllByMovie(Movie movie);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/MovieLikesRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/MovieLikesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/MovieLikesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,14 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.MovieLikesPK;
+import com.wediscussmovies.project.model.relation.MovieLikes;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface MovieLikesRepository extends JpaRepository<MovieLikes, MovieLikesPK> {
+    List<MovieLikes> findAllByUser(User user);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/MovieRatesRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/MovieRatesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/MovieRatesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,10 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.primarykeys.MovieRatesPK;
+import com.wediscussmovies.project.model.relation.MovieRates;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface MovieRatesRepository extends JpaRepository<MovieRates, MovieRatesPK> {
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/MovieRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/MovieRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/MovieRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,43 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.querymodels.MovieLikesQM;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import javax.transaction.Transactional;
+import java.util.List;
+import java.util.Optional;
+
+@Repository
+public interface MovieRepository extends JpaRepository<Movie, Integer> {
+     List<Movie> findAllByTitleLike(String Title);
+     List<Movie> findAllByDirector(Person director);
+     List<Movie> findAllByDirectorIsNull();
+     @Query(value="select m.movieId from Movie m")
+     List<Integer> findAllMovieIds();
+
+     @Query(value="select new com.wediscussmovies.project.model.Movie(m.movieId, m.title, m.imdbRating, m.imageUrl) from Movie m" +
+               " where m.movieId = :index")
+     Optional<Movie> findBasicById(@Param("index")Integer index);
+
+
+     @Query(value = "select new com.wediscussmovies.project.querymodels.MovieLikesQM(m.movieId, count(ml.id.userId)) from Movie m" +
+             " left join MovieLikes ml on ml.id.movieId = m.movieId" +
+             " group by m.movieId" +
+             " order by count(ml.id.userId) desc")
+     @Transactional
+     List<MovieLikesQM> findAllWithLikes();
+
+     @Query(value = "select new com.wediscussmovies.project.querymodels.MovieLikesQM(m.movieId, count(ml.id.userId)) from Movie m" +
+             " left join MovieLikes ml on ml.id.movieId = m.movieId" +
+             " group by m.movieId" +
+             " having m.movieId = :id")
+     @Transactional
+     List<MovieLikesQM> findLikesForMovie(@Param("id") Integer movie_id);
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/PersonRatesRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/PersonRatesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/PersonRatesRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,10 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.primarykeys.PersonRatesPK;
+import com.wediscussmovies.project.model.relation.PersonRates;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface PersonRatesRepository extends JpaRepository<PersonRates, PersonRatesPK> {
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/PersonRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/PersonRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/PersonRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,16 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.Person;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface PersonRepository extends JpaRepository<Person, Integer> {
+     List<Person> findAllByType(Character type);
+     List<Person> findAllByTypeAndNameLike(Character type, String name);
+     List<Person> findAllByTypeAndSurnameLike(Character type, String surname);
+    // Optional<Person> findPersonByPersonIdAndType(Integer id, Character type);
+     List<Person> findAllByTypeAndNameLikeOrSurnameLike(Character type,String name, String surname);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/ReplyRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/ReplyRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/ReplyRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,26 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.Reply;
+import com.wediscussmovies.project.model.primarykeys.ReplyPK;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import javax.transaction.Transactional;
+import java.sql.Date;
+import java.util.List;
+
+
+@Repository
+public interface ReplyRepository extends JpaRepository<Reply, ReplyPK> {
+    List<Reply> findAllByDiscussion(Discussion discussion);
+
+    @Modifying
+    @Query(value = "insert into project.replies (text,date,user_id,discussion_id) values(:text,:date,:user_id,:discussion_id)",nativeQuery = true)
+    @Transactional
+    void insertInto(@Param("text") String text, @Param("date")Date date,
+                    @Param("user_id")Integer userId,@Param("discussion_id")Integer discussionId);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/repository/UserRepository.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/repository/UserRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/repository/UserRepository.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,12 @@
+package com.wediscussmovies.project.repository;
+
+import com.wediscussmovies.project.model.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.Optional;
+
+@Repository
+public interface UserRepository extends JpaRepository<User, Integer> {
+     Optional<User> findByUsername(String username);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/DiscussionService.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/DiscussionService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/DiscussionService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,26 @@
+package com.wediscussmovies.project.service;
+
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.querymodels.DiscussionLikesQM;
+
+import java.util.List;
+
+public interface DiscussionService {
+    List<Discussion> listAll();
+    List<Discussion> listAllByTitle(String title);
+    Discussion findById(Integer id);
+    void save(Character type,Integer id, String title, String text, User user);
+    void edit(Integer discussionId,Character type,Integer id, String title, String text);
+    void deleteById(Integer discussionId);
+    void likeDiscussion(Integer discussionId,Integer userId);
+    void unlikeDiscussion(Integer discussionId,Integer userId);
+    List<Discussion> findAllForPersonOrMovie(Integer id,Character type);
+
+    List<Discussion> findLikedDiscussionsByUser(User user);
+
+    DiscussionLikesQM findLikesForDiscussionWithId(Integer discussionId);
+
+    List<DiscussionLikesQM> findLikesForAllDiscussions();
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/GenreService.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/GenreService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/GenreService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,19 @@
+package com.wediscussmovies.project.service;
+
+import com.wediscussmovies.project.model.Genre;
+import com.wediscussmovies.project.querymodels.GenreLikesQM;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public interface GenreService {
+    List<Genre> findAll();
+    Genre findById(Integer id);
+    List<Genre> findAllByType(String genre);
+    Genre save(String genreName);
+    List<GenreLikesQM> findAllWithLikes();
+    void likeGenre(Integer genreId,Integer userId);
+    void unlikeGenre(Integer genreId,Integer userId);
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/MovieService.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/MovieService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/MovieService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,41 @@
+package com.wediscussmovies.project.service;
+
+import com.wediscussmovies.project.ajaxmodels.Grade;
+import com.wediscussmovies.project.model.Genre;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.querymodels.MovieLikesQM;
+import org.springframework.data.jpa.repository.Query;
+
+import java.sql.Date;
+import java.util.List;
+
+public interface MovieService {
+     List<Movie> listAll();
+     List<Movie> listAllByType(Character type);
+     List<Movie> listAllWithoutDirector();
+     List<Movie> searchByTitle(String title);
+     Movie findById(Integer id);
+     Movie findBasicById(Integer id);
+     List<Integer> listAllIds();
+     Movie save(String title, String description, String imageUrl, Date airingDate,Double  rating,
+                Integer directorId,List<Integer> actorIds,List<Integer> genreIds);
+
+     Movie edit(Integer movieId,String title, String description, String imageUrl, Date airingDate,Double  rating,
+                Integer directorId,List<Integer> actorIds, List<Integer> genreIds);
+
+     List<Person> findAllActorsForMovie(Movie movie);
+     List<Genre> findAllGenresForMovie(Movie movie);
+
+     void likeMovie(Integer movieId, Integer userId);
+     void unlikeMovie(Integer movieId,Integer userId);
+
+     List<Movie> findLikedMoviesByUser(User user);
+
+     void deleteById(Integer id);
+
+     void addGradeMovie(Integer movieId, User user, Grade grade);
+
+    MovieLikesQM findLikesForMovieById(int movieId);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/PersonService.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/PersonService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/PersonService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,31 @@
+package com.wediscussmovies.project.service;
+
+import com.wediscussmovies.project.ajaxmodels.Grade;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.relation.MovieLikes;
+
+import java.sql.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public interface PersonService {
+    List<Person> findAll();
+     List<Person> findAllDirectors();
+     List<Person> findAllActors();
+    Person findById(Integer person_id);
+
+    Person  save(String name, String surname, Character type,
+                 Date birthDate, String image_url, String description, List<Integer> movieIds);
+
+    Person edit(Integer personId, String name, String surname, Character type,
+                Date birthDate, String image_url, String description, List<Integer> movieIds);
+
+    List<Person> findPersonsByNameOrSurname(Character type,String searchQuery);
+
+    List<Movie> findAllMoviesByPerson(Person person);
+
+    void deleteById(Integer id);
+    void addGradePerson(Integer personId, User user, Grade grade);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/ReplyService.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/ReplyService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/ReplyService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,21 @@
+package com.wediscussmovies.project.service;
+
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.Reply;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.ReplyPK;
+
+import java.util.List;
+
+public interface ReplyService {
+    Reply edit(Integer replyId, Integer discussionId, String text);
+    void delete(Integer discussionId,Integer replyId);
+    Reply findById(Integer discussionId, Integer replyId);
+    void save(Integer discussionId, String text, User user);
+    void likeReply(Integer replyId,Integer userId);
+    void unlikeReply(Integer replyId,Integer userId);
+    List<Reply> findAllByDiscussion(Discussion discussion);
+
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/UserService.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/UserService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/UserService.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,14 @@
+package com.wediscussmovies.project.service;
+
+import com.wediscussmovies.project.model.User;
+import org.springframework.security.core.userdetails.UserDetailsService;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Optional;
+
+public interface UserService extends UserDetailsService {
+     User findByUsername(String username);
+     User register(String email, String username, String password, String confirmPassword, String name, String surname);
+
+    User findById(Integer id);
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/impl/DiscussionServiceImpl.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/impl/DiscussionServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/impl/DiscussionServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,179 @@
+package com.wediscussmovies.project.service.impl;
+
+import com.wediscussmovies.project.model.exception.DiscussionNotExistException;
+import com.wediscussmovies.project.model.exception.MovieIdNotFoundException;
+import com.wediscussmovies.project.model.exception.PersonNotExistException;
+import com.wediscussmovies.project.model.exception.UserNotExistException;
+import com.wediscussmovies.project.model.primarykeys.DiscussionLikesPK;
+import com.wediscussmovies.project.model.relation.DiscussionLikes;
+import com.wediscussmovies.project.querymodels.DiscussionLikesQM;
+import com.wediscussmovies.project.repository.*;
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.service.DiscussionService;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@Service
+public class DiscussionServiceImpl implements DiscussionService {
+
+    private final DiscussionRepository discussionRepository;
+    private final DiscussionLikesRepository discussionLikesRepository;
+    private final UserRepository userRepository;
+
+    private final MovieRepository movieRepository;
+    private final PersonRepository personRepository;
+
+    public DiscussionServiceImpl(DiscussionRepository discussionRepository, DiscussionLikesRepository discussionLikesRepository, UserRepository userRepository,
+                                 MovieRepository movieRepository, PersonRepository personRepository) {
+        this.discussionRepository = discussionRepository;
+        this.discussionLikesRepository = discussionLikesRepository;
+        this.userRepository = userRepository;
+        this.movieRepository = movieRepository;
+        this.personRepository = personRepository;
+    }
+
+
+
+
+    @Override
+    public List<Discussion> listAll() {
+        List<Discussion> discussions = this.discussionRepository.findAll();
+        List<DiscussionLikesQM> discussionLikes  = this.discussionRepository.findAllDiscussionsWithLikes();
+        for (int i = 0; i < discussionLikes.size(); i++){
+            discussions.get(i).setLikes(discussionLikes.get(i).getLikes());
+        }
+        return discussions;
+    }
+
+    @Override
+    public void save(Character type,Integer id,String title, String text,User user) {
+        LocalDate date = LocalDate.now();
+        Discussion discussion;
+
+        if (type.equals('M')) {
+            discussion = new Discussion('M',text,title,date,user);
+            this.addMovieForDiscussion(id,discussion);
+        }
+        else{
+            discussion = new Discussion('P',text,title,date,user);
+            this.addPersonForDiscussion(id,discussion);
+        }
+
+
+
+        discussionRepository.save(discussion);
+    }
+
+    @Override
+    public void edit(Integer discussionId, Character type, Integer id, String title, String text) {
+        Discussion discussion = this.findById(discussionId);
+
+        discussion.setText(text);
+        discussion.setTitle(title);
+        discussion.setType(type);
+        discussion.setMovie(null);
+        discussion.setPerson(null);
+
+        if (type.equals('M')) {
+            this.addMovieForDiscussion(id,discussion);
+        }
+        else{
+          this.addPersonForDiscussion(id,discussion);
+        }
+        this.discussionRepository.save(discussion);
+
+    }
+
+    @Override
+    public void deleteById(Integer discussionId) {
+        this.discussionRepository.deleteById(discussionId);
+    }
+
+    @Override
+    public void likeDiscussion(Integer discussionId, Integer userId) {
+        Discussion discussion = discussionRepository.findById(discussionId).orElseThrow(() -> new DiscussionNotExistException(discussionId));
+        User user = userRepository.findById(userId).orElseThrow(() -> new UserNotExistException(userId.toString()));
+        this.discussionLikesRepository.save(new DiscussionLikes(discussion, user));
+    }
+
+    @Override
+    public List<Discussion> findLikedDiscussionsByUser(User user) {
+        List<DiscussionLikes> likes = discussionLikesRepository.findAllByUser(user);
+        List<Discussion> discussions = new ArrayList<>();
+        for(DiscussionLikes dl: likes){
+            discussions.add(dl.getDiscussion());
+        }
+        return discussions;
+    }
+
+    @Override
+    public void unlikeDiscussion(Integer discussionId, Integer userId) {
+        DiscussionLikesPK pk = new DiscussionLikesPK(discussionId, userId);
+        this.discussionLikesRepository.deleteById(pk);
+    }
+
+    @Override
+    public DiscussionLikesQM findLikesForDiscussionWithId(Integer discussionId) {
+//        return discussionRepository.findAllWithLikes().stream().filter(d ->  d.getDiscussionId().equals(discussionId)).findFirst().get();
+                return this.discussionRepository.findDiscussionWithLikes(discussionId);
+
+    }
+
+    @Override
+    public List<DiscussionLikesQM> findLikesForAllDiscussions() {
+           // return this.discussionRepository.findAllDiscussionsWithLikes();
+        return this.discussionRepository.findAllDiscussionsWithLikes();
+    }
+
+
+    @Override
+    public List<Discussion> findAllForPersonOrMovie(Integer id,Character type) {
+        if (type.equals('M'))
+        {
+            Movie movie = this.findMovieById(id);
+            return this.discussionRepository.findAllByMovie(movie);
+        }
+        Person person  = this.findPersonById(id);
+        return this.discussionRepository.findAllByPerson(person);
+
+    }
+
+    @Override
+    public Discussion findById(Integer id) {
+        Discussion disc =  discussionRepository.findById(id).orElseThrow(() -> new DiscussionNotExistException(id));
+        disc.setLikes(this.discussionRepository.findDiscussionWithLikes(id).getLikes());
+        return disc;
+    }
+
+    @Override
+    public List<Discussion> listAllByTitle(String title) {
+        if(title == null || title.isEmpty())
+         return this.listAll();
+        return discussionRepository.findAllByTitleLike("%"+title+"%");
+    }
+    private void addMovieForDiscussion(Integer id,Discussion discussion){
+        Movie movie = findMovieById(id);
+        discussion.setMovie(movie);
+
+    }
+
+    private void addPersonForDiscussion(Integer id, Discussion discussion){
+        Person person = findPersonById(id);
+        discussion.setPerson(person);
+
+    }
+    private Movie findMovieById(Integer id){
+        return this.movieRepository.findById(id).orElseThrow(() -> new MovieIdNotFoundException(id));
+    }
+    private Person findPersonById(Integer id){
+        return this.personRepository.findById(id).orElseThrow(() -> new PersonNotExistException(id));
+
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/impl/GenreServiceImpl.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/impl/GenreServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/impl/GenreServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,71 @@
+package com.wediscussmovies.project.service.impl;
+
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.exception.GenreNotExistException;
+import com.wediscussmovies.project.model.exception.UserNotExistException;
+import com.wediscussmovies.project.model.primarykeys.UserGenresPK;
+import com.wediscussmovies.project.model.relation.UserGenres;
+import com.wediscussmovies.project.querymodels.GenreLikesQM;
+import com.wediscussmovies.project.repository.GenreLikesRepository;
+import com.wediscussmovies.project.repository.GenreRepository;
+import com.wediscussmovies.project.model.Genre;
+import com.wediscussmovies.project.repository.UserRepository;
+import com.wediscussmovies.project.service.GenreService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class GenreServiceImpl implements GenreService {
+    private final GenreRepository genreRepository;
+    private final UserRepository userRepository;
+    private final GenreLikesRepository genreLikesRepository;
+
+
+    public GenreServiceImpl(GenreRepository genreRepository, UserRepository userRepository, GenreLikesRepository genreLikesRepository) {
+        this.genreRepository = genreRepository;
+        this.userRepository = userRepository;
+        this.genreLikesRepository = genreLikesRepository;
+    }
+
+    @Override
+    public Genre findById(Integer id) {
+        return this.genreRepository.findById(id).orElseThrow(() -> new GenreNotExistException(id));
+    }
+
+    @Override
+    public List<Genre> findAllByType(String genre) {
+        return this.genreRepository.findAllByGenreType(genre);
+    }
+
+    @Override
+    public Genre save(String genreName) {
+       Genre genre = new Genre(genreName);
+        return this.genreRepository.save(genre);
+    }
+
+    @Override
+    public List<GenreLikesQM> findAllWithLikes() {
+        // List<GenreLikes> genreLikesList = this.genreRepository.findAllWithLikes();
+       // genreLikesList.sort(GenreLikes.sorter);
+        return this.genreRepository.findAllWithLikes();
+    }
+
+    @Override
+    public List<Genre> findAll() {
+        return this.genreRepository.findAllSorted();
+    }
+
+    @Override
+    public void likeGenre(Integer genreId, Integer userId) {
+        User user = this.userRepository.findById(userId).orElseThrow(() -> new UserNotExistException(userId.toString()));
+        Genre genre = this.genreRepository.findById(genreId).orElseThrow(() -> new GenreNotExistException(genreId));
+        this.genreLikesRepository.save(new UserGenres(genre, user));
+    }
+
+    @Override
+    public void unlikeGenre(Integer genreId, Integer userId) {
+        UserGenresPK movieLikesPK = new UserGenresPK(userId, genreId);
+        this.genreLikesRepository.deleteById(movieLikesPK);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/impl/MovieServiceImpl.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/impl/MovieServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/impl/MovieServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,229 @@
+package com.wediscussmovies.project.service.impl;
+
+
+import com.wediscussmovies.project.ajaxmodels.Grade;
+import com.wediscussmovies.project.model.*;
+import com.wediscussmovies.project.model.exception.GenreNotExistException;
+import com.wediscussmovies.project.model.exception.PersonNotExistException;
+import com.wediscussmovies.project.model.exception.UserNotExistException;
+import com.wediscussmovies.project.model.primarykeys.MovieLikesPK;
+import com.wediscussmovies.project.model.primarykeys.MovieRatesPK;
+import com.wediscussmovies.project.model.relation.MovieActors;
+import com.wediscussmovies.project.model.relation.MovieGenres;
+import com.wediscussmovies.project.model.relation.MovieLikes;
+import com.wediscussmovies.project.model.relation.MovieRates;
+import com.wediscussmovies.project.querymodels.MovieLikesQM;
+import com.wediscussmovies.project.repository.*;
+import com.wediscussmovies.project.model.exception.MovieIdNotFoundException;
+import com.wediscussmovies.project.service.MovieService;
+import org.springframework.stereotype.Service;
+
+import javax.swing.text.html.Option;
+import javax.transaction.Transactional;
+import java.sql.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class MovieServiceImpl implements MovieService {
+
+    private final MovieRepository movieRepository;
+    private final PersonRepository personRepository;
+    private final GenreRepository genreRepository;
+    private final MovieActorsRepository movieActorsRepository;
+    private final MovieGenresRepository movieGenresRepository;
+    private final UserRepository userRepository;
+    private final MovieLikesRepository movieLikesRepository;
+    private final MovieRatesRepository movieRatesRepository;
+
+    public MovieServiceImpl(MovieRepository movieRepository, PersonRepository personRepository,
+                            GenreRepository genreRepository, MovieActorsRepository movieActorsRepository,
+                            MovieGenresRepository movieGenresRepository,
+                            UserRepository userRepository, MovieLikesRepository movieLikesRepository,
+                            MovieRatesRepository movieRatesRepository) {
+
+        this.movieRepository = movieRepository;
+        this.personRepository = personRepository;
+        this.genreRepository = genreRepository;
+        this.movieActorsRepository = movieActorsRepository;
+        this.movieGenresRepository = movieGenresRepository;
+        this.userRepository = userRepository;
+        this.movieLikesRepository = movieLikesRepository;
+        this.movieRatesRepository = movieRatesRepository;
+    }
+
+    @Override
+    public List<Movie> listAll() {
+        return this.movieRepository.findAll();
+    }
+
+    @Override
+    public List<Movie> listAllByType(Character type) {
+        if (type.equals('A'))
+            return this.listAll();
+        return this.listAllWithoutDirector();
+    }
+
+    @Override
+    public List<Movie> listAllWithoutDirector() {
+        return this.movieRepository.findAllByDirectorIsNull();
+    }
+
+    @Override
+    public Movie findById(Integer id) {
+        return this.movieRepository.findById(id).orElseThrow(() -> new MovieIdNotFoundException(id));
+    }
+
+    @Override
+    public Movie findBasicById(Integer id) {
+        return this.movieRepository.findBasicById(id).orElseThrow(() -> new MovieIdNotFoundException(id));
+    }
+
+    @Override
+    public MovieLikesQM findLikesForMovieById(int movieId) {
+        return this.movieRepository.findLikesForMovie(movieId).get(0);
+    }
+
+    @Override
+    public List<Integer> listAllIds() {
+        return this.movieRepository.findAllMovieIds();
+    }
+
+    @Override
+    @Transactional
+    public Movie save(String title, String description, String imageUrl,
+                      Date airingDate, Double rating, Integer directorId,List<Integer> actorIds,List<Integer> genreIds) {
+
+
+        Person director =getDirector(directorId);
+        Movie movie = new Movie(title,description,imageUrl,airingDate,rating,director);
+       movie = this.movieRepository.saveAndFlush(movie);
+       addActorsAndGenresForMovie(movie,actorIds,genreIds);
+       return movie;
+    }
+
+
+    @Transactional
+    @Override
+    public Movie edit(Integer movieId, String title, String description,
+                      String imageUrl, Date airingDate, Double rating,
+                      Integer directorId, List<Integer> actorIds,List<Integer> genreIds) {
+
+
+        Person director =getDirector(directorId);
+        Movie movie = this.findById(movieId);
+
+        movie.setTitle(title);
+        movie.setDescription(description);
+        movie.setImageUrl(imageUrl);
+        movie.setAiringDate(airingDate);
+        movie.setImdbRating(rating);
+        movie.setDirector(director);
+
+        this.movieActorsRepository.deleteAllByMovie(movie);
+        this.movieGenresRepository.deleteAllByMovie(movie);
+
+        movie = this.movieRepository.save(movie);
+        this.addActorsAndGenresForMovie(movie,actorIds,genreIds);
+
+        return movie;
+    }
+
+    @Override
+    public List<Person> findAllActorsForMovie(Movie movie) {
+        return this.movieActorsRepository.findAllByMovie(movie)
+                .stream()
+                .map(MovieActors::getPerson)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public List<Genre> findAllGenresForMovie(Movie movie) {
+        return this.movieGenresRepository.findAllByMovie(movie)
+                .stream()
+                .map(MovieGenres::getGenre)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public void likeMovie(Integer movieId, Integer userId) {
+        User user = this.userRepository.findById(userId).orElseThrow(() -> new UserNotExistException(userId.toString()));
+        Movie movie = this.findById(movieId);
+
+        this.movieLikesRepository.save(new MovieLikes(movie, user));
+    }
+
+    @Override
+    public void unlikeMovie(Integer movieId, Integer userId) {
+        MovieLikesPK movieLikesPK = new MovieLikesPK(movieId,userId);
+        this.movieLikesRepository.deleteById(movieLikesPK);
+    }
+
+    @Override
+    public List<Movie> findLikedMoviesByUser(User user) {
+        return
+                this.movieLikesRepository
+                        .findAllByUser(user)
+                        .stream()
+                        .map(MovieLikes::getMovie)
+                        .collect(Collectors.toList());
+    }
+
+
+    @Override
+    public void deleteById(Integer id) {
+        this.movieRepository.deleteById(id);
+    }
+
+    @Override
+    public void addGradeMovie(Integer movieId, User user, Grade grade) {
+        MovieRatesPK key =  new MovieRatesPK(movieId, user.getUserId());
+        Optional<MovieRates> movieRates = this.movieRatesRepository.findById(key);
+        if (movieRates.isPresent()){
+           MovieRates rates = movieRates.get();
+            rates.setReason(grade.getReason());
+            rates.setStarsRated(grade.getRating());
+            this.movieRatesRepository.save(rates);
+        }
+        else{
+            Movie movie = this.findById(movieId);
+            MovieRates rates = new MovieRates(user,movie,grade.getReason(),grade.getRating());
+            this.movieRatesRepository.save(rates);
+        }
+    }
+
+    @Override
+    public List<Movie> searchByTitle(String title) {
+        return this.movieRepository.findAllByTitleLike("%"+title+"%");
+    }
+
+    @Transactional
+    void addActorsAndGenresForMovie(Movie movie, List<Integer> actorIds, List<Integer> genreIds)
+    {
+
+        actorIds.stream()
+                .map(this::findPersonById)
+                .forEach(actor -> this.movieActorsRepository.save(new MovieActors(movie,actor)));
+
+        genreIds.stream()
+                .map(this::findGenreById)
+                .forEach(genre -> this.movieGenresRepository.save(new MovieGenres(movie,genre)));
+
+    }
+    private Person getDirector(Integer directorId){
+
+        if (directorId != null)
+            return this.findPersonById(directorId);
+        return null;
+
+    }
+    private Person findPersonById(Integer id){
+        return this.personRepository.findById(id).orElseThrow(() -> new PersonNotExistException(id));
+    }
+    private Genre findGenreById(Integer id){
+        return this.genreRepository.findById(id).orElseThrow(() -> new GenreNotExistException(id));
+    }
+}
+
+
Index: Sources/src/main/java/com/wediscussmovies/project/service/impl/PersonServiceImpl.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/impl/PersonServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/impl/PersonServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,183 @@
+package com.wediscussmovies.project.service.impl;
+
+import com.wediscussmovies.project.ajaxmodels.Grade;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.exception.MovieHasAlreadyDirector;
+import com.wediscussmovies.project.model.exception.MovieIdNotFoundException;
+import com.wediscussmovies.project.model.exception.PersonNotExistException;
+import com.wediscussmovies.project.model.primarykeys.PersonRatesPK;
+import com.wediscussmovies.project.model.relation.MovieActors;
+import com.wediscussmovies.project.model.relation.MovieLikes;
+import com.wediscussmovies.project.model.relation.PersonRates;
+import com.wediscussmovies.project.repository.*;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.service.PersonService;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.sql.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class PersonServiceImpl implements PersonService {
+
+    private final PersonRepository personRepository;
+    private final MovieRepository movieRepository;
+    private final MovieActorsRepository movieActorsRepository;
+    private final PersonRatesRepository personRatesRepository;
+    public PersonServiceImpl(PersonRepository personRepository,
+                             MovieRepository movieRepository, MovieActorsRepository movieActorsRepository,
+                             PersonRatesRepository personRatesRepository) {
+        this.personRepository = personRepository;
+        this.movieRepository = movieRepository;
+        this.movieActorsRepository = movieActorsRepository;
+        this.personRatesRepository = personRatesRepository;
+    }
+
+    @Override
+    public List<Person> findAll() {
+        return this.personRepository.findAll();
+    }
+
+    @Override
+    public List<Person> findAllDirectors() {
+        return this.personRepository.findAllByType('D');
+    }
+
+    @Override
+    public Person findById(Integer id) {
+        return this.personRepository.findById(id).orElseThrow(() -> new PersonNotExistException(id));
+    }
+
+
+
+    @Override
+    public List<Person> findAllActors() {
+        return this.personRepository.findAllByType('A');
+    }
+
+    @Override
+    @Transactional
+    public Person save(String name, String surname, Character type, Date birthDate, String image_url,
+                       String description,List<Integer> movieIds) {
+
+        Person person = this.personRepository.saveAndFlush(new Person(name,surname,type,birthDate,image_url,description));
+
+        if (movieIds!= null) {
+            if (type.equals('A'))
+                this.addActorForMovies(person, movieIds);
+            else
+                this.addDirectorForMovies(person, movieIds);
+        }
+         return person;
+
+    }
+
+    @Override
+    @Transactional
+    public Person edit(Integer personId, String name, String surname,
+                       Character type, Date birthDate, String image_url, String description, List<Integer> movieIds) {
+        Person person = this.findById(personId);
+
+        person.setName(name);
+        person.setSurname(surname);
+        person.setDateOfBirth(birthDate);
+        person.setImageUrl(image_url);
+        person.setType(type);
+        person.setDescription(description);
+
+
+        person = this.personRepository.saveAndFlush(person);
+
+            this.movieActorsRepository.deleteAllByPerson(person);
+            this.removeMovieDirectorsBeforeEdit(person);
+        if (movieIds != null) {
+            if (type.equals('A'))
+                this.addActorForMovies(person, movieIds);
+            else
+                this.addDirectorForMovies(person, movieIds);
+        }
+
+        return person;
+
+    }
+
+    @Override
+    public List<Person> findPersonsByNameOrSurname(Character type,String searchQuery) {
+        if (searchQuery != null && searchQuery.isEmpty())
+            return this.personRepository.findAllByTypeAndNameLikeOrSurnameLike(type,searchQuery,searchQuery);
+        if (type.equals('D'))
+            return this.findAllDirectors();
+        return this.findAllActors();
+
+    }
+
+    @Override
+    public List<Movie> findAllMoviesByPerson(Person person) {
+        if (person.getType().equals('A'))
+            return this.movieActorsRepository
+                .findAllByPerson(person)
+                .stream()
+                .map(MovieActors::getMovie)
+                .collect(Collectors.toList());
+        return this.movieRepository.findAllByDirector(person);
+    }
+
+    @Override
+    public void deleteById(Integer id) {
+        this.personRepository.deleteById(id);
+    }
+
+    @Override
+    public void addGradePerson(Integer personId, User user, Grade grade) {
+        PersonRatesPK key =  new PersonRatesPK(personId, user.getUserId());
+        Optional<PersonRates> personRates = this.personRatesRepository.findById(key);
+        if (personRates.isPresent()){
+            PersonRates rates = personRates.get();
+            rates.setReason(grade.getReason());
+            rates.setStarsRated(grade.getRating());
+            this.personRatesRepository.save(rates);
+        }
+        else{
+            Person person = this.findById(personId);
+            PersonRates rates = new PersonRates(user,person,grade.getReason(),grade.getRating());
+            this.personRatesRepository.save(rates);
+        }
+
+    }
+
+
+
+    private void addActorForMovies(Person person, List<Integer> movieIds){
+
+        movieIds.stream()
+                .map(this::findMovieById)
+                .forEach(m -> this.movieActorsRepository.save(new MovieActors(m,person)));
+
+    }
+    private void addDirectorForMovies(Person person, List<Integer> movieIds){
+        movieIds.stream()
+                .map(this::findMovieById)
+                .forEach(m -> this.addMovieDirector(m,person));
+    }
+    private void addMovieDirector(Movie movie,Person person){
+        Person director = movie.getDirector();
+        if (director != null)
+            throw new MovieHasAlreadyDirector(movie.getTitle(),director.getName(),director.getSurname());
+        movie.setDirector(person);
+        this.movieRepository.save(movie);
+    }
+    private void removeMovieDirectorsBeforeEdit(Person person){
+        this.movieRepository.findAllByDirector(person)
+                .forEach(m ->{ m.setDirector(null); this.movieRepository.save(m); });
+
+    }
+
+    private Movie findMovieById(Integer id){
+        return this.movieRepository.findById(id).orElseThrow(() -> new MovieIdNotFoundException(id));
+    }
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/impl/ReplyServiceImpl.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/impl/ReplyServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/impl/ReplyServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,78 @@
+package com.wediscussmovies.project.service.impl;
+
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.exception.DiscussionNotExistException;
+import com.wediscussmovies.project.model.exception.ReplyNotExistException;
+import com.wediscussmovies.project.model.primarykeys.ReplyPK;
+import com.wediscussmovies.project.repository.DiscussionRepository;
+import com.wediscussmovies.project.repository.ReplyRepository;
+import com.wediscussmovies.project.model.Reply;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.repository.UserRepository;
+import com.wediscussmovies.project.service.ReplyService;
+import org.springframework.stereotype.Service;
+
+import java.sql.Date;
+import java.time.LocalDate;
+import java.util.List;
+
+@Service
+public class ReplyServiceImpl implements ReplyService {
+
+    private final ReplyRepository replyRepository;
+    private final DiscussionRepository discussionRepository;
+
+    public ReplyServiceImpl(ReplyRepository replyRepository,
+                            DiscussionRepository discussionRepository) {
+        this.replyRepository = replyRepository;
+        this.discussionRepository = discussionRepository;
+    }
+
+
+
+    @Override
+    public void save(Integer discussionId, String text,User user) {
+
+        Discussion discussion = this.discussionRepository.findById(discussionId).orElseThrow(() -> new DiscussionNotExistException(discussionId));
+
+        Date date = Date.valueOf(LocalDate.now());
+        this.replyRepository.insertInto(text,date,user.getUserId(),discussionId);
+
+    }
+
+    @Override
+    public void likeReply(Integer replyId, Integer userId) {
+        //da se implementira, promena vo baza
+    }
+
+    @Override
+    public void unlikeReply(Integer replyId, Integer userId) {
+        // da se implementira, promena vo baza
+    }
+
+    @Override
+    public List<Reply> findAllByDiscussion(Discussion discussion) {
+        return this.replyRepository.findAllByDiscussion(discussion);
+    }
+
+
+    @Override
+    public Reply edit(Integer replyId,Integer discussionId,String text) {
+        ReplyPK replyPK = new ReplyPK(discussionId,replyId);
+        Reply reply = this.replyRepository.findById(replyPK).orElseThrow();
+        reply.setText(text);
+        return  this.replyRepository.save(reply);
+    }
+
+    @Override
+    public void delete(Integer discussionId, Integer replyId) {
+        this.replyRepository.deleteById(new ReplyPK(discussionId,replyId));
+    }
+
+    @Override
+    public Reply findById(Integer discussionId, Integer replyId) {
+        ReplyPK replyPK  = new ReplyPK(discussionId,replyId);
+        return this.replyRepository.findById(replyPK).orElseThrow(() -> new ReplyNotExistException(replyPK));
+
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/service/impl/UserServiceImpl.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/service/impl/UserServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/service/impl/UserServiceImpl.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,58 @@
+package com.wediscussmovies.project.service.impl;
+
+import com.wediscussmovies.project.model.exception.InvalidArgumentsException;
+import com.wediscussmovies.project.model.exception.PasswordsDoNotMatchException;
+import com.wediscussmovies.project.model.exception.UserNotExistException;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.exception.UsernameAlreadyExistsException;
+import com.wediscussmovies.project.repository.UserRepository;
+import com.wediscussmovies.project.service.UserService;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+@Service
+public class UserServiceImpl implements UserService {
+
+    private final UserRepository userRepository;
+    private final PasswordEncoder passwordEncoder;
+
+
+    public UserServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder) {
+        this.userRepository = userRepository;
+        this.passwordEncoder = passwordEncoder;
+    }
+
+    @Override
+    public User findByUsername(String username) {
+        return this.userRepository.findByUsername(username).orElseThrow(() -> new UserNotExistException(username));
+    }
+
+
+
+    @Override
+    public User register( String email, String username, String password, String confirmPassword
+                                  , String name, String surname) {
+
+        if ( username.isEmpty() || password.isEmpty())
+            throw new InvalidArgumentsException();
+        if (!password.equals(confirmPassword))
+            throw new PasswordsDoNotMatchException();
+        if(this.userRepository.findByUsername(username).isPresent())
+            throw new UsernameAlreadyExistsException(username);
+        User user = new User(email,username,passwordEncoder.encode(password),name,surname);
+        return userRepository.save(user);
+
+    }
+
+    @Override
+    public User findById(Integer id) {
+        return userRepository.findById(id).orElseThrow(() -> new UserNotExistException(id.toString()));
+    }
+
+    @Override
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+        return this.findByUsername(username);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/DesignFrontMovies.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/DesignFrontMovies.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/DesignFrontMovies.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,17 @@
+package com.wediscussmovies.project.web;
+
+import com.wediscussmovies.project.model.Movie;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DesignFrontMovies {
+    public static  void designMovieList(List<Movie> movieList, List<List<Movie>> movie_rows){
+        for(int i=0; i<movieList.size(); i+=4){
+            int j = i+4;
+            if(j>movieList.size())
+                j= movieList.size();
+            movie_rows.add(movieList.subList(i, j));
+        }
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/HomeController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/HomeController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/HomeController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,7 @@
+package com.wediscussmovies.project.web;
+
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class HomeController {
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/PageFrontMovies.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/PageFrontMovies.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/PageFrontMovies.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,42 @@
+package com.wediscussmovies.project.web;
+
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.service.MovieService;
+import org.springframework.ui.Model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PageFrontMovies {
+    public static List<Movie> getPagedMovies(String page, MovieService movieService, Model model){
+        List<Integer> movieIds = movieService.listAllIds();
+        List<Movie> movies = new ArrayList<>();
+        if(page==null || Integer.parseInt(page) <= 0)
+            page="1";
+        int pageToLoad = Integer.parseInt(page);
+
+        int from = (pageToLoad-1)*12;
+        int to = pageToLoad*12;
+
+        if (from>movieIds.size()){
+            page = "1";
+            pageToLoad = Integer.parseInt(page);
+            from = (pageToLoad-1)*12;
+            to = pageToLoad*12;
+        }
+        else if(to>movieIds.size()){
+            to = movieIds.size();
+        }
+
+        movieIds = movieIds.subList(from, to);
+
+        for(Integer id: movieIds){
+            //Trying to improve load times by not pulling all things from the database, excluding un-needed stuff
+            //
+            //movies.add(movieService.findById(id));
+            movies.add(movieService.findBasicById(id));
+        }
+        model.addAttribute("page", page);
+        return movies;
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/DiscussionController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/DiscussionController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/DiscussionController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,200 @@
+package com.wediscussmovies.project.web.controller;
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.model.Discussion;
+import com.wediscussmovies.project.model.Reply;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.relation.DiscussionLikes;
+import com.wediscussmovies.project.querymodels.DiscussionLikesQM;
+import com.wediscussmovies.project.service.DiscussionService;
+import com.wediscussmovies.project.service.MovieService;
+import com.wediscussmovies.project.service.PersonService;
+import com.wediscussmovies.project.service.ReplyService;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Controller
+@RequestMapping("/discussions")
+public class DiscussionController {
+
+    private final DiscussionService discussionService;
+    private final ReplyService replyService;
+    private final MovieService movieService;
+    private final PersonService personService;
+
+    public DiscussionController(DiscussionService discussionService, ReplyService replyService, MovieService movieService, PersonService personService) {
+        this.discussionService = discussionService;
+        this.replyService = replyService;
+        this.movieService = movieService;
+        this.personService = personService;
+    }
+
+    @GetMapping()
+    public String getDiscussions(@RequestParam(required = false) String titleSearch,
+                                    Model model){
+        /* 1.Validacija i  na frontend so, da ne se isprakja baranjeto, ako titleSearch e null ili empty
+         da ne se preoptovaruva serverot so baranja za titleSearch koga e null!
+
+         */
+        //List<Discussion> discussions = discussionService.listAllByTitle(titleSearch);
+        List<Discussion> discussions = discussionService.listAll();
+        model.addAttribute("discussions", discussions);
+        model.addAttribute("contentTemplate", "discussionsList");
+        model.addAttribute("user",LoggedUser.getLoggedUser());
+        this.addModelPropertiesForUser(model);
+       // this.addModelPropertiesLikes(model,null, discussions);
+        return "template";
+    }
+
+    @GetMapping("/{id}")
+    public String getDiscussion(
+            @PathVariable Integer id,
+            Model model){
+        /*
+            2. Moze da se vrati indikator deka takva diskusija ne postoi! - postaveno
+         */
+        try {
+            Discussion disc = discussionService.findById(id);
+            model.addAttribute("disc", disc);
+            model.addAttribute("contentTemplate", "discussion");
+            model.addAttribute("replies",this.replyService.findAllByDiscussion(disc));
+            addModelPropertiesForUser(model);
+
+            return "template";
+        }
+        catch (RuntimeException exception){
+            return "redirect:/discussions?error="+exception.getMessage();
+
+        }
+    }
+    @GetMapping("/all/{id}")
+    public String getDiscussionForId(@PathVariable Integer id,@RequestParam Character type, Model model){
+
+        model.addAttribute("discussions", this.discussionService.findAllForPersonOrMovie(id,type));
+        model.addAttribute("contentTemplate", "discussionForType");
+        return "template";
+
+    }
+
+    @GetMapping("/{id}/replies")
+    public String getRepliesToDiscussion(
+            @PathVariable Integer id,
+            Model model){
+
+        try {
+            Discussion discussion = discussionService.findById(id);
+            model.addAttribute("discussion", discussion);
+            model.addAttribute("contentTemplate", "discussionReply");
+            return "template";
+        }
+        catch (RuntimeException exception){
+            return "redirect:/discussions?error="+exception.getMessage();
+
+        }
+
+    }
+
+
+    @GetMapping("/add/{id}")
+    public String getFormForEdit(Model model,
+                                           @PathVariable Integer id)
+    {
+        Discussion discussion = this.discussionService.findById(id);
+        setModelPropertiesForForm(model);
+        model.addAttribute("discussion", discussion);
+
+        return "template";
+    }
+    @GetMapping("/add")
+    public String getFormForAdd(Model model)
+    {
+        setModelPropertiesForForm(model);
+
+        return "template";
+    }
+
+
+    @PostMapping("/save")
+    public String saveDiscussion(
+           @RequestParam Integer idDiscussed,
+            @RequestParam String title,
+            @RequestParam String text,
+            @RequestParam Character type    ){
+
+
+
+        try{
+
+            discussionService.save(type,idDiscussed, title, text, LoggedUser.getLoggedUser());
+            return "redirect:/discussions";
+
+        }
+
+        catch (RuntimeException exc){
+            return "redirect:/discussions?error="+exc.getMessage();
+
+        }
+    }
+
+    @PostMapping("/save/{discussionId}/")
+    public String editDiscussion(
+                                               @PathVariable Integer discussionId,
+                                               @RequestParam String title,
+                                               @RequestParam String text,
+                                               @RequestParam Character type,
+                                               @RequestParam Integer idDiscussed
+                                               ){
+
+
+
+
+        try{
+
+
+            discussionService.edit(discussionId,type,idDiscussed, title, text);
+            return "redirect:/discussions";
+
+        }
+
+        catch (RuntimeException exc){
+            return "redirect:/discussions?error="+exc.getMessage();
+
+        }
+    }
+
+    private void setModelPropertiesForForm(Model model){
+        model.addAttribute("movies",this.movieService.listAll());
+        model.addAttribute("persons",this.personService.findAll());
+        model.addAttribute("contentTemplate", "discussionsAdd");
+
+    }
+    private void addModelPropertiesForUser(Model model){
+        User user = LoggedUser.getLoggedUser();
+        model.addAttribute("likedDiscussions",this.discussionService.findLikedDiscussionsByUser(user));
+        model.addAttribute("user",user);
+    }
+    private void addModelPropertiesLikes(Model model, Discussion discussion, List<Discussion> discussions){
+        // ispagja kompliciran kod vaka, podobro da dodademe i svojstvo u diskusijata i koga ke se dodade lajk
+        // soodvetno da se zgoleme i obratno
+//        if(discussion==null){
+//            List<DiscussionLikesQM> discussionLikes = new ArrayList<>();
+//            for(Discussion d: discussions){
+//                discussionLikes.add(discussionService.findLikesForDiscussionWithId(d.getDiscussionId()));
+//            }
+//            model.addAttribute("likes", discussionLikes);
+//        }
+//        else{
+//            model.addAttribute("likes",discussionService.findLikesForDiscussionWithId(discussion.getDiscussionId()).getLikes());
+//        }
+    }
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/GenreController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/GenreController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/GenreController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,46 @@
+package com.wediscussmovies.project.web.controller;
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.model.Genre;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.relation.UserGenres;
+import com.wediscussmovies.project.repository.GenreLikesRepository;
+import com.wediscussmovies.project.service.GenreService;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Controller
+@RequestMapping("/genres")
+public class GenreController {
+    private final GenreService genreService;
+    private final GenreLikesRepository genreLikesRepository;
+
+    public GenreController(GenreService genreService, GenreLikesRepository genreLikesRepository) {
+        this.genreService = genreService;
+        this.genreLikesRepository = genreLikesRepository;
+    }
+    @GetMapping
+    public String getGenres(Model model){
+        model.addAttribute("genres",genreService.findAllWithLikes());
+        model.addAttribute("allGenres", genreService.findAll());
+        model.addAttribute("contentTemplate","genres");
+        addModelPropertiesForUser(model);
+        return "template";
+    }
+
+    private void addModelPropertiesForUser(Model model){
+        User user = LoggedUser.getLoggedUser();
+        List<UserGenres> genreLikesList = this.genreLikesRepository.findAllByUser(user);
+        List<Genre> genres = new ArrayList<>();
+        for(UserGenres g: genreLikesList){
+            genres.add(genreService.findById(g.getId().getGenreId()));
+        }
+        model.addAttribute("likedGenres",genres);
+        model.addAttribute("user",user);
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/MovieController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/MovieController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/MovieController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,206 @@
+package com.wediscussmovies.project.web.controller;
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.querymodels.MovieLikesQM;
+import com.wediscussmovies.project.service.GenreService;
+import com.wediscussmovies.project.service.MovieService;
+import com.wediscussmovies.project.service.PersonService;
+import com.wediscussmovies.project.web.DesignFrontMovies;
+import com.wediscussmovies.project.web.PageFrontMovies;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+import java.sql.Date;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+
+@Controller
+@RequestMapping("/movies")
+public class MovieController {
+    private final MovieService movieService;
+    private final GenreService genreService;
+    private final PersonService personService;
+
+    public MovieController(MovieService movieService, GenreService genreService, PersonService personService) {
+        this.movieService = movieService;
+        this.genreService = genreService;
+        this.personService = personService;
+    }
+
+    @GetMapping("/old")
+    public String getMoviesOld(@RequestParam(required = false) String titleQuery, Model model,
+                            @RequestParam(required = false) String error){
+        List<Movie> movies;
+        if(titleQuery == null ) {
+            movies = movieService.listAll();
+        }
+        else{
+            movies = movieService.searchByTitle(titleQuery);
+        }
+
+        addModelPropertiesForUser(model);
+
+        List<List<Movie>> movie_rows = new ArrayList<>();
+        DesignFrontMovies.designMovieList(movies,movie_rows);
+        model.addAttribute("movies", movies);
+        model.addAttribute("movie_rows", movie_rows);
+        model.addAttribute("contentTemplate", "moviesList");
+        model.addAttribute("genres", genreService.findAll());
+        if (error != null && !error.equals(" "))
+            model.addAttribute("error",error);
+        return "template";
+    }
+
+
+    @GetMapping
+    public String getMovies(@RequestParam(required = false) String titleQuery, Model model,
+                            @RequestParam(required = false) String error, @RequestParam(required = false) String page){
+        if (page==null){
+            return "redirect:/movies?page=1";
+        }
+        addModelPropertiesForUser(model);
+        List<Movie> movies = PageFrontMovies.getPagedMovies(page, movieService, model);
+        List<List<Movie>> movie_rows = new ArrayList<>();
+        DesignFrontMovies.designMovieList(movies,movie_rows);
+        //addModelPropertiesForMoviesLikes(model, movies);
+        model.addAttribute("movies", movies);
+        model.addAttribute("movie_rows", movie_rows);
+        model.addAttribute("genres", genreService.findAll());
+        model.addAttribute("contentTemplate", "moviesListPaged");
+        if (error != null && !error.equals(" "))
+            model.addAttribute("error",error);
+        return "template";
+    }
+
+    @GetMapping("/{id}")
+    public String getMovie(@PathVariable Integer id, Model model){
+        model.addAttribute("movie", movieService.findById(id));
+        addModelPropertiesForUser(model);
+        model.addAttribute("likes", movieService.findLikesForMovieById(id).getLikes());
+        model.addAttribute("contentTemplate", "movieShow");
+        return "template";
+    }
+
+    @GetMapping("/add")
+    public String addMovie(Model model){
+
+        addModelProperties(model);
+        model.addAttribute("contentTemplate", "moviesAdd");
+        return "template";
+    }
+
+
+    @GetMapping("/{id}/delete")
+    public String deleteMovie(@PathVariable Integer id){
+
+       try {
+           this.movieService.deleteById(id);
+           return "redirect:/movies";
+
+       }
+       catch (RuntimeException exc){
+           return "redirect:/movies?error="+exc.getMessage();
+       }
+    }
+
+    @PostMapping("/save")
+    public String saveMovie(
+
+
+
+            @RequestParam String title,
+                               @RequestParam String description,
+                               @RequestParam String imageUrl,
+                               @RequestParam(required = false) Double rating,
+                               @RequestParam(required = false) Integer directorId,
+                               @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate airingDate,
+                               @RequestParam List<Integer> actors,
+                               @RequestParam List<Integer> genres
+                            ){
+
+        try {
+            Movie movie = this.movieService.save(title,description,imageUrl,Date.valueOf(airingDate),rating,directorId,actors,genres);
+
+            return "redirect:/movies";
+        }
+        catch (RuntimeException exc){
+            return "redirect:/movies?error="+exc.getMessage();
+        }
+    }
+    @PostMapping("/save/{movieId}")
+    public String updateMovie(
+
+
+            @PathVariable Integer movieId,
+            @RequestParam String title,
+            @RequestParam String description,
+            @RequestParam String imageUrl,
+            @RequestParam(required = false) Double rating,
+            @RequestParam(required = false) Integer directorId,
+            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate airingDate,
+            @RequestParam List<Integer> actors,
+            @RequestParam List<Integer> genres
+    ){
+
+        try {
+            Movie movie = this.movieService.edit(movieId,title,description,imageUrl,Date.valueOf(airingDate),rating,directorId,actors,genres);
+
+            return "redirect:/movies";
+        }
+        catch (RuntimeException exc){
+            return "redirect:/movies?error="+exc.getMessage();
+        }
+    }
+
+
+
+    @GetMapping("/{id}/edit")
+    public String editMovie(@PathVariable Integer id, Model model){
+        try {
+            Movie movie = movieService.findById(id);
+            addModelProperties(model);
+            model.addAttribute("movie", movie);
+            model.addAttribute("director",movie.getDirector());
+            model.addAttribute("movieActors",movieService.findAllActorsForMovie(movie));
+            model.addAttribute("movieGenres",movieService.findAllGenresForMovie(movie));
+            model.addAttribute("contentTemplate", "moviesAdd");
+            return "template";
+
+        }
+        catch (RuntimeException exc){
+            return "redirect:/movies?error="+exc.getMessage();
+        }
+
+    }
+    private void addModelProperties(Model model){
+        model.addAttribute("directors", personService.findAllDirectors());
+        model.addAttribute("actors", personService.findAllActors());
+        model.addAttribute("genres", genreService.findAll());
+    }
+    private void addModelPropertiesForUser(Model model){
+        User user = LoggedUser.getLoggedUser();
+        model.addAttribute("likedMovies",this.movieService.findLikedMoviesByUser(user));
+        model.addAttribute("user",user);
+    }
+    private void addModelPropertiesForMoviesLikes(Model model, List<Movie> movies){
+        HashMap<Integer,MovieLikesQM> movieLikes = new HashMap<>();
+        for(Movie m: movies){
+            movieLikes.put(m.getMovieId(),movieService.findLikesForMovieById(m.getMovieId()));
+        }
+        model.addAttribute("movieLikes", movieLikes);
+    }
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/PersonController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/PersonController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/PersonController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,145 @@
+package com.wediscussmovies.project.web.controller;
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.model.Person;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.service.MovieService;
+import com.wediscussmovies.project.service.PersonService;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.sql.Date;
+import java.util.List;
+
+@Controller
+public class PersonController {
+    private final PersonService personService;
+    private final MovieService movieService;
+
+    public PersonController(PersonService personService, MovieService movieService) {
+        this.personService = personService;
+        this.movieService = movieService;
+    }
+
+    /*
+    1. Prebaruvanjeto po ime i prezime posoodvetno e da bide na frontend
+        Da ne se preoptovaruva server i klient da ceka koga moze vo browser vekje dobieni da se filtrirat
+     */
+    @GetMapping("/actors")
+    public String getActors(Model model, @RequestParam(required = false) String nameAndSurname){
+        List<Person> persons = personService.findPersonsByNameOrSurname('A',nameAndSurname);
+        model.addAttribute("persons", persons);
+        model.addAttribute("contentTemplate", "personsList");
+
+        return "template";
+    }
+    /*
+      2. Prebaruvanjeto po ime i prezime posoodvetno e da bide na frontend
+          Da ne se preoptovaruva server i klient da ceka koga moze vo browser vekje dobieni da se filtrirat
+       */
+    @GetMapping("/directors")
+    public String getDirectors(Model model, @RequestParam(required = false) String nameAndSurname){
+        List<Person> persons = personService.findPersonsByNameOrSurname('D',nameAndSurname);
+        model.addAttribute("persons", persons);
+        model.addAttribute("contentTemplate", "personsList");
+        return "template";
+    }
+
+    @GetMapping("/persons/{id}")
+    public String getPerson(@PathVariable Integer id, Model model){
+        Person person = personService.findById(id);
+        //Error handling, could be null!!!!!!!!!
+        model.addAttribute("person", person);
+        addModelPropertiesForUser(model);
+        model.addAttribute("contentTemplate", "personShow");
+        return "template";
+    }
+
+    @GetMapping("/persons/add")
+    public String addingFormForPerson( Model model){
+
+        addModelPropertiesForForm(model);
+        return "template";
+    }
+    @GetMapping("persons/edit/{personId}")
+    public String editPerson(@PathVariable Integer personId, Model model){
+
+        try {
+            Person person = this.personService.findById(personId);
+            addModelPropertiesForForm(model);
+            model.addAttribute("person",person);
+            model.addAttribute("movieActors",this.personService.findAllMoviesByPerson(person));
+            return "template";
+        }
+        catch (RuntimeException exc){
+            return "redirect:/actors?erorr="+exc.getMessage();
+        }
+    }
+
+    @PostMapping("/persons/save")
+    public String savePerson(
+            @RequestParam String name,
+            @RequestParam String surname,
+            @RequestParam Character type,
+            @RequestParam Date birthDate,
+            @RequestParam String imageUrl,
+            @RequestParam String description,
+            @RequestParam(required = false) List<Integer> movieIds){
+
+        String returnedUrl = getReturnedUrl(type);
+
+        try {
+
+            Person person = this.personService.save(name, surname, type, birthDate, imageUrl, description, movieIds);
+           return returnedUrl;
+        }
+        catch (RuntimeException exc){
+            return returnedUrl + "?error" + exc.getMessage();
+        }
+
+    }
+    @PostMapping("/persons/save/{personId}")
+    public String editPerson(
+            @PathVariable Integer personId,
+            @RequestParam String name,
+            @RequestParam String surname,
+            @RequestParam Character type,
+            @RequestParam Date birthDate,
+            @RequestParam String imageUrl,
+            @RequestParam String description,
+            @RequestParam(required = false) List<Integer> movieIds){
+
+        String returnedUrl = getReturnedUrl(type);
+        try {
+
+            Person person = this.personService.edit(personId,name, surname, type, birthDate, imageUrl, description, movieIds);
+            return returnedUrl;
+        }
+        catch (RuntimeException exc){
+            return returnedUrl + "?error" + exc.getMessage();
+        }
+
+    }
+    private String getReturnedUrl(Character type){
+        if (type.equals('A'))
+           return   "redirect:/actors";
+        return "redirect:/directors";
+    }
+    private void addModelPropertiesForForm(Model model){
+        model.addAttribute("contentTemplate", "personsAdd");
+        model.addAttribute("moviesActors",this.movieService.listAllByType('A'));
+        model.addAttribute("moviesDirectors",this.movieService.listAllByType('D'));
+
+    }
+
+    private void addModelPropertiesForUser(Model model){
+        User user = LoggedUser.getLoggedUser();
+        model.addAttribute("user",user);
+    }
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/ReplyController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/ReplyController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/ReplyController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,85 @@
+package com.wediscussmovies.project.web.controller;
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.model.Reply;
+import com.wediscussmovies.project.model.User;
+import com.wediscussmovies.project.model.primarykeys.ReplyPK;
+import com.wediscussmovies.project.service.ReplyService;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+
+@Controller
+@RequestMapping("/replies")
+public class ReplyController {
+    private final ReplyService replyService;
+
+    public ReplyController(ReplyService replyService) {
+        this.replyService = replyService;
+    }
+
+    @GetMapping("/add/{discussionId}")
+    public String addForm(@PathVariable Integer discussionId, Model model){
+        model.addAttribute("discussionId",discussionId);
+        model.addAttribute("contentTemplate","repliesAdd");
+        return "template";
+    }
+
+    @GetMapping("/edit/{discussionId}/{replyId}")
+    public String editForm(@PathVariable Integer discussionId,@PathVariable Integer replyId, Model model){
+
+        try {
+            Reply reply = replyService.findById(discussionId,replyId);
+            model.addAttribute("reply", reply);
+            model.addAttribute("contentTemplate", "repliesAdd");
+            return "template";
+
+
+        }catch (RuntimeException exc){
+            return "redirect:/discussions?error="+exc.getMessage();
+
+        }
+    }
+    @PostMapping("/save")
+    public String saveReply(
+            @RequestParam Integer discussionId,
+            @RequestParam String text){
+
+        try {
+
+            this.replyService.save(discussionId,text, LoggedUser.getLoggedUser());
+            return "redirect:/discussions/"+discussionId;
+
+        }
+        catch (RuntimeException exc){
+            return "redirect:/discussions?error="+exc.getMessage();
+
+        }
+    }
+
+    @PostMapping("/save/{replyId}")
+    public String editReply(
+                            @PathVariable Integer replyId,
+                            @RequestParam Integer discussionId,
+                            @RequestParam String text){
+
+        /*
+            1. Da se realizira so ajax baranje na restController
+         */
+        try {
+            Reply reply = replyService.edit(replyId,discussionId, text);
+
+            return "redirect:/discussions/" + reply.getDiscussion().getDiscussionId();
+        }
+        catch (RuntimeException exc){
+            return "redirect:/discussions?error="+exc.getMessage();
+        }
+
+    }
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/UsersController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/UsersController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/UsersController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,79 @@
+package com.wediscussmovies.project.web.controller;
+
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.model.Movie;
+import com.wediscussmovies.project.model.exception.InvalidArgumentsException;
+import com.wediscussmovies.project.model.exception.PasswordsDoNotMatchException;
+import com.wediscussmovies.project.service.MovieService;
+import com.wediscussmovies.project.service.UserService;
+import com.wediscussmovies.project.web.DesignFrontMovies;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Controller
+@RequestMapping
+public class UsersController{
+    private  final UserService userService;
+    private final MovieService movieService;
+
+    public UsersController(UserService userService, MovieService movieService) {
+        this.userService = userService;
+        this.movieService = movieService;
+    }
+    @PostMapping("/register")
+    public String register(@RequestParam String username,
+                           @RequestParam String password,
+                           @RequestParam String repeatedPassword,
+                           @RequestParam String email,
+                           @RequestParam String name,
+                           @RequestParam String surname) {
+        try{
+            this.userService.register(email,username,password,repeatedPassword,name,surname);
+            return "redirect:/login";
+        } catch (InvalidArgumentsException | PasswordsDoNotMatchException exception) {
+            return "redirect:/register?error=" + exception.getMessage();
+        }
+    }
+    @GetMapping("/profiles/{id}")
+    public String getProfilePage(@PathVariable Integer id, Model model){
+        model.addAttribute("user",userService.findById(id));
+        model.addAttribute("contentTemplate","usersShow");
+        return "template";
+    }
+    @GetMapping("/register")
+    public String getRegisterPage(@RequestParam(required = false) String error, Model model) {
+        addModelError(model,error);
+        model.addAttribute("contentTemplate","register");
+        return "template";
+    }
+    @GetMapping("/login")
+    public String getLoginPage(@RequestParam(required = false) String error,Model model){
+        addModelError(model,error);
+        model.addAttribute("contentTemplate","login");
+        return "template";
+    }
+
+    private void addModelError(Model model,String error){
+        if(error != null && !error.isEmpty()) {
+            model.addAttribute("hasError", true);
+            model.addAttribute("error", error);
+        }
+    }
+    @GetMapping("/favoriteList")
+    public String getFavoriteList(Model model){
+        List<Movie> movieList = this.movieService.findLikedMoviesByUser(LoggedUser.getLoggedUser());
+        List<List<Movie>> movie_rows = new ArrayList<>();
+        DesignFrontMovies.designMovieList(movieList,movie_rows);
+        model.addAttribute("movie_rows", movie_rows);
+        model.addAttribute("contentTemplate","favoriteList");
+        return "template";
+
+    }
+
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/DiscussionRestController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/DiscussionRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/DiscussionRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,46 @@
+package com.wediscussmovies.project.web.controller.rest;
+
+import com.wediscussmovies.project.service.DiscussionService;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("api/discussions")
+public class DiscussionRestController {
+    private final DiscussionService discussionService;
+
+    public DiscussionRestController(DiscussionService discussionService) {
+        this.discussionService = discussionService;
+    }
+    @DeleteMapping("/delete/{id}")
+    public ResponseEntity deleteById(@PathVariable Integer id){
+        try {
+            this.discussionService.deleteById(id);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+
+        }
+    }
+    @GetMapping("/like/{discussionId}")
+    public ResponseEntity likeDiscussion(@PathVariable Integer discussionId, @RequestParam Integer userId){
+        try {
+            this.discussionService.likeDiscussion(discussionId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+    @GetMapping("/unlike/{discussionId}")
+    public ResponseEntity unlikeDiscussion(@PathVariable Integer discussionId, @RequestParam Integer userId){
+        try {
+            this.discussionService.unlikeDiscussion(discussionId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/GenreRestController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/GenreRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/GenreRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,38 @@
+package com.wediscussmovies.project.web.controller.rest;
+
+import com.wediscussmovies.project.service.DiscussionService;
+import com.wediscussmovies.project.service.GenreService;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("api/genres")
+public class GenreRestController {
+    private final GenreService genreService;
+
+    public GenreRestController(GenreService genreService) {
+        this.genreService = genreService;
+    }
+
+    @GetMapping("/like/{genreId}")
+    public ResponseEntity likeGenre(@PathVariable Integer genreId, @RequestParam Integer userId){
+        try {
+            this.genreService.likeGenre(genreId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+    @GetMapping("/unlike/{genreId}")
+    public ResponseEntity unlikeGenre (@PathVariable Integer genreId, @RequestParam Integer userId){
+        try {
+            this.genreService.unlikeGenre(genreId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            System.out.println(exception.getMessage());
+            return ResponseEntity.ok(false);
+        }
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/MovieRestController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/MovieRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/MovieRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,67 @@
+package com.wediscussmovies.project.web.controller.rest;
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.ajaxmodels.Grade;
+import com.wediscussmovies.project.service.MovieService;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/movies")
+public class MovieRestController {
+
+    private final MovieService movieService;
+
+
+    public MovieRestController(MovieService movieService) {
+        this.movieService = movieService;
+    }
+
+    @DeleteMapping("/delete/{id}")
+    public ResponseEntity deleteById(@PathVariable Integer id){
+        try {
+            this.movieService.deleteById(id);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+
+        }
+    }
+    @GetMapping("/like/{movieId}")
+    public ResponseEntity likeMovie(@PathVariable Integer movieId, @RequestParam Integer userId){
+        try {
+            this.movieService.likeMovie(movieId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+    @GetMapping("/unlike/{movieId}")
+    public ResponseEntity unlikeMovie(@PathVariable Integer movieId, @RequestParam Integer userId){
+        try {
+            this.movieService.unlikeMovie(movieId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+    @PostMapping("/grade/{movieId}")
+    public ResponseEntity addGrade(@PathVariable Integer movieId, @RequestBody Grade grade){
+        try {
+            if(grade.getRating() < 5)
+                grade.setRating(5);
+            else if(grade.getRating()>10)
+                grade.setRating(10);
+            this.movieService.addGradeMovie(movieId, LoggedUser.getLoggedUser(),grade);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+
+    }
+
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/PersonRestController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/PersonRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/PersonRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,41 @@
+package com.wediscussmovies.project.web.controller.rest;
+
+import com.wediscussmovies.project.LoggedUser;
+import com.wediscussmovies.project.ajaxmodels.Grade;
+import com.wediscussmovies.project.service.PersonService;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/persons")
+public class PersonRestController {
+
+    private final PersonService personService;
+
+    public PersonRestController(PersonService personService) {
+        this.personService = personService;
+    }
+
+    @DeleteMapping("/delete/{id}")
+    public ResponseEntity deletePerson(@PathVariable Integer id){
+
+        try {
+            this.personService.deleteById(id);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+    @PostMapping("/grade/{personId}")
+    public ResponseEntity addGrade(@PathVariable Integer personId, @RequestBody Grade grade){
+        try {
+            this.personService.addGradePerson(personId, LoggedUser.getLoggedUser(),grade);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+
+    }
+}
Index: Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/ReplyRestController.java
===================================================================
--- Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/ReplyRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
+++ Sources/src/main/java/com/wediscussmovies/project/web/controller/rest/ReplyRestController.java	(revision 980eeda285ff3ffb16a3a043cf9c4086a8686f85)
@@ -0,0 +1,51 @@
+package com.wediscussmovies.project.web.controller.rest;
+
+import com.wediscussmovies.project.model.primarykeys.ReplyPK;
+import com.wediscussmovies.project.service.ReplyService;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("api/replies")
+public class ReplyRestController {
+
+    private final ReplyService replyService;
+
+    public ReplyRestController(ReplyService replyService) {
+        this.replyService = replyService;
+    }
+
+    @PostMapping("/delete/{discussionId}")
+    public ResponseEntity deleteById(@RequestParam Integer replyId,@PathVariable Integer discussionId){
+        try {
+            this.replyService.delete(discussionId,replyId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+
+        }
+    }
+    @GetMapping("/like/{replyId}")
+    public ResponseEntity likeReply(@PathVariable Integer replyId,
+                                    @RequestParam Integer userId){
+        try {
+            this.replyService.likeReply(replyId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+    @GetMapping("/unlike/{replyId}")
+    public ResponseEntity unlikeReply(@PathVariable Integer replyId,
+                                 @RequestParam Integer userId){
+        try {
+            this.replyService.unlikeReply(replyId,userId);
+            return ResponseEntity.ok(true);
+        }
+        catch (RuntimeException exception){
+            return ResponseEntity.ok(false);
+        }
+    }
+}
