Spring boot entity has a list of another entity - spring-boot

I have a problem with the following code:
#Entity
#Table(name = "app_user")
#NoArgsConstructor
#AllArgsConstructor
#Data
#Builder
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(unique = true)
private String username;
#Column(unique = true)
private String email;
private String name;
private String password;
#Enumerated(EnumType.STRING)
private Role role;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
#JoinTable(name = "user_shoes",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "shoes_id"))
private List<Shoe> shoes = new ArrayList<>();
#Builder.Default
private final Instant created = new Date().toInstant();
}
#Entity
#Table(name = "shoes")
#NoArgsConstructor
#AllArgsConstructor
#Data
#Builder
public class Shoe {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private User user;
private String brand;
private String type;
private String size;
private String color;
private String image_url;
private String sex;
#Builder.Default
private Instant created = new Date().toInstant();
}
Inside User entity I want to make a list that contains Shoe entities, but I always get an error.
Table 'webshop.shoes' doesn't exist
Anybody know how to fix this problem?
It is required to my home project of a shoe webshop.
Thanks.

I had pretty similar codes with yours.
Please see mine and hope you solve it as I did.
import com.fasterxml.jackson.annotation.JsonBackReference;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
#Entity
#Getter
#Table(name = "orders")
#ToString(exclude = "user")
#NoArgsConstructor(access = AccessLevel.PROTECTED)
#EntityListeners(AuditingEntityListener.class)
#SequenceGenerator(
name = "order_seq_generator"
, sequenceName = "orders_order_id_seq"
, initialValue = 1
, allocationSize = 1
)
public class Order {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE
, generator = "order_seq_generator")
#Column(name = "order_id")
private Long orderId;
#Column(name = "order_number")
private String orderNumber;
#Column(name = "salad_date")
private LocalDate saladDate;
#Column(name = "order_date")
#CreatedDate
private LocalDateTime orderDate;
#ManyToOne
#JsonBackReference
#JoinColumn(name = "user_id")
private User user;
#Column(name = "cancel_yn", columnDefinition = "boolean default false")
private boolean cancelYn;
#Builder
public Order(String orderNumber, User user, LocalDate saladDate, boolean cancelYn) {
this.orderNumber = orderNumber;
this.user = user;
this.saladDate = saladDate;
this.cancelYn = cancelYn;
}
public void updateOrder(String orderNumber, boolean cancelYn) {
this.orderNumber = orderNumber;
this.cancelYn = cancelYn;
}
}
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
#Entity
#Getter
#ToString
#Table(name = "users")
#NoArgsConstructor(access = AccessLevel.PROTECTED)
#EntityListeners(AuditingEntityListener.class)
#SequenceGenerator(
name= "users_seq_generator"
, sequenceName = "users_user_id_seq"
, initialValue = 1
, allocationSize = 1
)
public class User {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE
, generator = "users_seq_generator")
#Column(name = "user_id")
private Long userId;
#Column(name = "password")
private String password;
#Column(name = "user_email")
private String userEmail;
#JsonIgnore
#JsonManagedReference // Avoid infinite recursion
#OneToMany(mappedBy = "user", cascade = CascadeType.PERSIST)
private List<Order> orders = new ArrayList<>();
#Column(name = "user_sabun")
private String userSabun;
#Column(name = "user_name")
private String userName;
#Column(name = "user_phone")
private String userPhone;
#Column(name = "send_email_yn")
private boolean sendEmailYn;
#Column(name = "join_date")
#CreatedDate
private LocalDateTime joinDate;
#Builder
public User(Long userId, String userEmail, String password, String userSabun, String userName, String userPhone, boolean sendEmailYn, LocalDateTime joinDate) {
this.userId = userId;
this.userEmail = userEmail;
this.password = password;
this.userSabun = userSabun;
this.userName = userName;
this.userPhone = userPhone;
this.sendEmailYn = sendEmailYn;
this.joinDate = joinDate;
}
public void userUpdate(String userEmail, String userSabun, String userName, String userPhone, boolean sendEmailYn) {
this.userEmail = userEmail;
this.userSabun = userSabun;
this.userName = userName;
this.userPhone = userPhone;
this.sendEmailYn = sendEmailYn;
}
}

Related

REST API Infinite loop

My API shows me infinite loop for adress field
When I insert #JsonIgnore, #JsonManagedReference or #JsonBackReference
I can clearly see one result as it should be, but than i don't have nested address fields.
What should I do to have also that address fields but one result?
These are my main entities:
1.Property
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Data;
#Entity
#Data
#Table(name = "property")
public class Property {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_property")
private int id_property;
#Column(name = "title")
private String title;
#Column(name = "type")
private String type;
#Column(name = "room")
private String room;
#Column(name = "price")
private double price;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "address_id_address")
// #JsonBackReference
private Address address;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "user_id_user")
// #JsonBackReference
private User user;
}
User
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
#Entity
#Getter
#Setter
#Table(name = "user")
class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_user")
private int id_user;
#Column(name = "username")
private String username;
#Column(name = "name")
private String name;
#Column(name = "lastname")
private String lastname;
#Column(name = "phone")
private String phone;
#Column(name = "notes")
private String notes;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "user_address_id_user_address")
// #JsonManagedReference
private UserAddress userAddress;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
// #JsonManagedReference
private List<Property> property = new ArrayList<>();
}
Address
package com.realestate.petfriendly.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
#Entity
#Getter
#Setter
#Table(name="address")
class Address{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_address")
private int id_address;
#Column(name = "city")
private String city;
#Column(name = "municipality")
private String municipality;
#Column(name = "place")
private String place;
#Column(name = "street")
private String street;
#Column(name = "house_number")
private double house_number;
#OneToOne(mappedBy = "address")
// #JsonManagedReference
private Property property;
}
You actually have the solution to your problem in your code, but the key annotations are commented-out and in the wrong places (according to your requirements). One of the ways to tackle this is by using #JsonManagedReference and #JsonBackReference as follows:
#Entity
#Data
#Table(name = "property")
public class Property {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_property")
private int id_property;
#Column(name = "title")
private String title;
#Column(name = "type")
private String type;
#Column(name = "room")
private String room;
#Column(name = "price")
private double price;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "address_id_address")
#JsonManagedReference
private Address address;
#ManyToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "user_id_user")
#JsonBackReference
private User user;
}
#Entity
#Getter
#Setter
#Table(name = "user")
class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_user")
private int id_user;
#Column(name = "username")
private String username;
#Column(name = "name")
private String name;
#Column(name = "lastname")
private String lastname;
#Column(name = "phone")
private String phone;
#Column(name = "notes")
private String notes;
#OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
#JoinColumn(name = "user_address_id_user_address")
private UserAddress userAddress;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "user")
#JsonManagedReference
private List<Property> property = new ArrayList<>();
}
#Entity
#Getter
#Setter
#Table(name="address")
class Address{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_address")
private int id_address;
#Column(name = "city")
private String city;
#Column(name = "municipality")
private String municipality;
#Column(name = "place")
private String place;
#Column(name = "street")
private String street;
#Column(name = "house_number")
private double house_number;
#OneToOne(mappedBy = "address")
#JsonBackReference
private Property property;
}
Keep in mind the following:
#JsonManagedReference is the forward part of the relationship: the one that gets serialized normally.
#JsonBackReference is the back part of the relationship: it will be omitted from serialization.
If you want to have a reference to the back part of the relationship, you can use #JsonIdentityInfo as follows:
#Entity
#Data
#Table(name = "property")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_property")
public class Property {
(...)
}
#Entity
#Getter
#Setter
#Table(name = "user")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_user")
class User {
(...)
}
#Entity
#Getter
#Setter
#Table(name="address")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id_address")
class Address{
(...)
}
You can read more about these and other techniques in the following online resource: https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion.
You have circular dependency between Property and Address class. In order to block infinite JSON serialization loop you can add #JsonIgnore annotation on one side of related properties

(Do not display relationship values)

I have two entity with name of the article and article Category.
and they have one-to-many relationships.
I use #JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class,property = "id")
but I cant see data of article category(category_id) in spring data rest.
ArticleCategory.class
#Entity
#Table(name = "article_category")
#Getter
#Setter
public class ArticleCategory implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "category_name")
private String categoryName;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "articleCategory", fetch = FetchType.LAZY)
private Set<Article> articles = new HashSet<>();
}
Article.class
#Entity
#Table(name = "article")
#Getter
#Setter
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Article implements Serializable {
public Article() {
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "category_id", nullable = false)
private ArticleCategory articleCategory;
#Column(name = "title")
private String title;
#Column(name = "image_url")
private String image_url;
#Column(name = "short_description")
private String short_description;
#Column(name = "text")
private String text;
#Column(name = "keywords", nullable = true)
private String keywords;
#Column(name = "visit", nullable = false)
private int visit;
#Column(name = "code", nullable = false)
private UUID code;
#Column(name = "date_created")
#CreationTimestamp
private Date dateCreated;
#Column(name = "date_updated", nullable = false)
#UpdateTimestamp
private Date dateUpdated;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id")
private User user;
public Article(String title, String image_url, String short_description, String text, String keywords, int visit, UUID code) {
this.title = title;
this.image_url = image_url;
this.short_description = short_description;
this.text = text;
this.keywords = keywords;
this.visit = visit;
this.code = code;
}
}
Article Repository
#CrossOrigin("http://localhost:4200")
#RepositoryRestResource(collectionResourceRel = "article", path = "article")
public interface ArticleRepository extends JpaRepository<Article,Long> {
Article findByCode(UUID uuid);
}
And this is output of spring data rest
enter image description here
That is exactly because you used #JsonManagedReference and #JsonBackReference. Keep in mind the following when using them:
#JsonManagedReference is the forward part of the relationship and is the one that gets serialized normally.
#JsonBackReference is the back part of the relationship and it will be omitted from serialization.
The serialized Article object does not contain a reference to the ArticleCategory object.
If you want to have any ArticleCategory data when serializing Article you can either use #JsonIdentityInfo so that one of the properties is serialized (in this case I've chosen id for both):
#Entity
#Table(name = "article")
#Getter
#Setter
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Article implements Serializable{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "category_id", nullable = false)
private ArticleCategory articleCategory;
}
#Entity
#Table(name = "article_category")
#Getter
#Setter
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class ArticleCategory implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "category_name")
private String categoryName;
#OneToMany(cascade = CascadeType.ALL,mappedBy = "articleCategory" ,fetch = FetchType.LAZY)
private Set<Article> articles=new HashSet<>();
}
If you are only interested in categoryId another possibility would be to use #JsonIgnore on private Set<Article> articles property so that it is not serialized:
#Entity
#Table(name = "article_category")
#Getter
#Setter
public class ArticleCategory implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "category_name")
private String categoryName;
#JsonIgnore
#OneToMany(cascade = CascadeType.ALL,mappedBy = "articleCategory" ,fetch = FetchType.LAZY)
private Set<Article> articles=new HashSet<>();
}
If none of those suits your needs you might need to implement your own custom serializer. You can read more about all those options at https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion.
I solved the problem using the controller
And that's why #JsonManageRefrence and #JsonBackRefrence do not work
I replaced the lazy load with the eager load in both entity
#ManyToOne(fetch = FetchType.Eager)
#JoinColumn(name = "user_id")
#JsonManageRefrence
private User user;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "articleCategory",
fetch = FetchType.Eager)
#JsonBackRefrence
private Set<Article> articles = new HashSet<>();
and then add a controller
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
#RestController
#RequestMapping("/getAllArticle")
public class MyController {
private ArticleRepository articleRepository;
// you must do constructor injection
#GetMapping("/getAllArticle")
public List<Article> allArticle()
{
return articleRepository.findAll();
}
}

How to set join for predicate

I have a entity for product:
package com.javaschool.entity;
import lombok.*;
import javax.persistence.*;
import java.util.Set;
#EqualsAndHashCode(of = {"id"})
#ToString(of = { "id", "quantity", "price", "model"})
#Entity
#Table(name = "products")
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Product {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(name = "quantity")
private int quantity;
#Column(name = "price")
private int price;
#Column(name = "model")
private String model;
#Column(name = "is_active")
private boolean active;
#Column(name = "picture_url")
private String url;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "category_id")
private Category category;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "brand_id")
private Brand brand;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "season_id")
private Season season;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "color_id")
private Color color;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "material_id")
private Material material;
#ManyToOne(fetch = FetchType.EAGER, optional = false)
#JoinColumn(name = "size_id")
private Size size;
#ManyToMany(mappedBy = "productSet", fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Order> orderSet;
}
I want to filter by category, season, color, brand and other related parameters
At the moment my filtering function looks like this. It works for parameters such as model, price, quantity. That is, for those that are data in this table and not from others. How can I filter by parameters that are taken from other tables?
#Override
public List<Product> findByParam(List<SearchCriteria> params) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root<Product> root = criteriaQuery.from(Product.class);
Predicate predicate = criteriaBuilder.conjunction();
ProductSearchQueryCriteriaConsumer productConsumer = new ProductSearchQueryCriteriaConsumer(predicate, criteriaBuilder, root);
params.stream().forEach(productConsumer);
predicate = productConsumer.getPredicate();
criteriaQuery.where(criteriaBuilder.equal(root.get(Product_.active), true),
predicate);
List<Product> result = entityManager.createQuery(criteriaQuery).getResultList();
return result;
}
I thought that you can make such a call and everything will work. But I was wrong.
List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("season_id", ":", "3"));
List<ProductDto> productDtoList = productService.getProductsByParam(params);
My SearchCriteria
#Data
#AllArgsConstructor
#NoArgsConstructor
public class SearchCriteria {
private String key;
private String operation;
private Object value;
}
Need to make this:
List<SearchCriteria> params = new ArrayList<SearchCriteria>();
params.add(new SearchCriteria("category", ":", categoryRepository.findById(1)));
That is, in the searchcriteria for the value object, pass an object of this class to filter by

Spring JPA 2 nested many to many relationship

I am having a problem with my many to many relationship. Basically, here is what I am trying to do.
I have 2 many to many tables that are nested, as seen on the following image.
Db diagram
When compiling my code, I get the following error:
Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'weeks0_.employee_project_employee_id' in 'field list'
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1003) ~[mysql-connector-java-8.0.18.jar:8.0.18]
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-3.4.1.jar:na]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.1.jar:na]
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:57) ~[hibernate-core-5.4.6.Final.jar:5.4.6.Final]
So I understand that I have a problem with the weeks.
here are my entities:
Week:
package com.achsogo.rpt.entity;
import javax.persistence.*;
import java.util.Set;
#Entity
#Table(name="week")
public class Week {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int weekNumber;
private int year;
#OneToMany(mappedBy = "week", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProjectWeek> employeeProjects;
public Week() {
}
public Week(int weekNumber, int year) {
this.weekNumber = weekNumber;
this.year = year;
} //Getter and Setters
Project:
import javax.persistence.*;
import java.util.*;
#Entity
#Table(name = "project")
public class Project {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String alias;
private String pspElement;
private int contractValue;
private int plannedCost;
private int plannedHours;
private int assignedHours;
private Date startDate;
private Date endDate;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "project", orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<ProjectAP> projectAPS;
#ManyToOne
private Department department;
#OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProject> employees;
//Empty constructor
public Project(){}
//constructor for new project with default names
public Project(String alias){
this.alias = alias;
}
Employee:
#Entity
#Table(name = "employee")
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String email;
private int employeeNumber;
private String acronym;
private int availability;
#OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProject> projects;
#ManyToOne
private Department department;
#ManyToOne
private Role role;
Table between Project and Employee (with the class to create the ID):
EmployeeProjectID:
#Embeddable
public class EmployeeProjectId implements Serializable {
private Long projectId;
private Long employeeId;
private EmployeeProjectId(){}
public EmployeeProjectId(Long projectId, Long employeeId){
this.employeeId = employeeId;
this.projectId = projectId;
}
EmployeeProject: It is here that the weeks are being called (If I am not mistaken)
#Entity
#Table(name = "project_employee")
public class EmployeeProject {
#EmbeddedId
private EmployeeProjectId id;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("projectId")
private Project project;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("employeeId")
private Employee employee;
#Column(name = "amount_time")
private int amountTime = 0;
#Column(name = "is_project_leader")
private boolean isProjectLeader = false;
#OneToMany(mappedBy = "employeeProject", cascade = CascadeType.ALL, orphanRemoval = true, fetch =
FetchType.EAGER)
private Set<EmployeeProjectWeek> weeks;
public EmployeeProject(){}
And now the table between Week and Employee Project:
EmployeeProjectWeekId: To create the ID for the nested many to many table:
#Embeddable
public class EmployeeProjectWeekId implements Serializable {
private EmployeeProjectId employeeProjectId;
private Long weekId;
private EmployeeProjectWeekId(){}
And finally the EmployeeProjectweek:
#Entity
#Table(name="project_employee_week")
public class EmployeeProjectWeek {
#EmbeddedId
private EmployeeProjectWeekId id;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("weekId")
private Week week;
#ManyToOne(fetch = FetchType.EAGER)
#MapsId("employeeProjectId")
private EmployeeProject employeeProject;
#Column(name="amount_time")
private int amountTime = 0;
#Column(name="is_project_leader")
private boolean isProjectLeader= false;
public EmployeeProjectWeek(Week week, EmployeeProject employeeProject) {
this.week = week;
this.employeeProject = employeeProject;
this.id = new EmployeeProjectWeekId(employeeProject.getId(), week.getId());
}
Does anyone has a clue where I have done an error? Thanks in advance for your time!
It was a naming problem. I solved this by dropping all the tables in my DB and having Spring to automatically generate the tables. Now everything works well.
I entered the following lines in my application.properties:
spring.jpa.hibernate.ddl=true
spring.jpa.hibernate.ddl-auto=update

Error creating table with Spring Boot and Postgres

I am trying to create an application using Spring and Postgres. Currently I have 3 Entities: User, Role and UserRole.
User
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import javax.persistence.*;
#Data
#Entity
#Builder
#AllArgsConstructor
public class User {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "user_id", nullable = false)
private Long id;
#Column(name = "username", nullable = false, unique = true)
private String username;
#Column(name = "password", nullable = false)
private String password;
#Column(name = "name", nullable = false)
private String firstName;
#Column(name = "lastName", nullable = true)
private String lastName;
#Column(name = "gender", nullable = false)
private char gender;
#Column(name = "email", nullable = true)
private String email;
public User() {}
public User(String username, String password, String firstName, String lastName, char gender, String email) {
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.gender = gender;
this.email = email;
}
}
Role
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import javax.persistence.*;
#Data
#Entity
#Builder
#AllArgsConstructor
public class Role {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "role_id", nullable = false)
private Long id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "description", nullable = false)
private String description;
public Role () {}
public Role (String name, String description) {
this.name = name;
this.description = description;
}
}
UserRole
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.persistence.*;
#Data
#Entity
#AllArgsConstructor
public class UserRole {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(name = "user_role_id")
private Long id;
#OneToOne
#JoinColumn(name = "user_id")
private User user;
#OneToOne
#JoinColumn(name = "role_id")
private Role role;
public UserRole () {}
public UserRole (User user, Role role) {
this.user = user;
this.role = role;
}
}
When running the application, Role and UserRole tables are created in the database correctly, but its not the case with User table. I will appreciate your help :).
user is a reserved keyword in postgresql because of which it is not allowing to create the table with this name. Try with another name.

Resources