JPA do not allow binary one to many relationship - spring-boot

I have 2 entities as below:
Course
#Entity
public class Course {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(mappedBy = "course", cascade = {CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE})
private List<Comment> comments;
Comment
#Entity
public class Comment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String comment;
#ManyToOne(targetEntity = Course.class)
private Course course; //Error: 'Many To One' attribute type should not be 'Course'
I follow luv2code.com course but he use Spring MVC and it work just find, but when I do this in spring boot, it always show the error, please help me fix this!

Try something like this:
#Entity
public class Course {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(mappedBy = "course")
private List<Comment> comments;
And your comment entity:
#Entity
public class Comment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String comment;
#ManyToOne(cascade = CascadeType.ALL)
private Course course;

#Entity
public class Course {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
orphanRemoval = true)
private List<Comment> comments = new ArrayList<Comment>();
#Entity
public class Comment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String comment;
}
You don't to define ManyToOne Mapping in your comment Entity.

Related

One to one bi direction mapping is not working

My code contains two entities, that have relation with each other.
Student Class :
#Entity
#Table(name = "student")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "student_detail_id")
private StudentDetail studentDetail;
public Student() {}
//getters setters
StudentDetail Class :
#Entity
#Table(name = "student_detail")
public class StudentDetail {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "college")
private String college;
#Column(name = "no_of_problems_solved")
private int noOfProblemsSolved;
public StudentDetail() {}
#Column(name = "college")
private String college;
#Column(name = "no_of_problems_solved")
private int noOfProblemsSolved;
public StudentDetail() {}
Why is the one to one bi direction mapping not working?
In Student_Detail you have to specify #OntToOne Annotation also.
#Entity
#Table(name = "student_detail")
public class StudentDetail {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "college")
private String college;
#Column(name = "no_of_problems_solved")
private int noOfProblemsSolved;
#OneToOne(mappedBy = "studentDetail", cascade = CascadeType.ALL)
private Student student;
//Getters setters
}
This should work for you.

Rest api creation for multiple path variables

I need to fetch names of all students who have enrolled for the courses.
Url:-/students/{course1}/{course2}
Eg /students/java/oracle
How to write controller, service and repository in rest api.
Entity:-
Student
Integer Id,String name and list coursenames
What about?
#Controller
#RequestMapping("/students")
public class StudentController {
#Autowired
private StudentService studentService;
// /students/java,oracle
#GetMapping(value="/{courses}")
#ResponseBody
public String getStudents(#PathVariable String[] courses) {
return studentService.getStudents(courses);
}
}
Student
#Entity
#Table(name = "student")
public class StudentDao {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
#OneToMany(fetch = FetchType.EAGER)
#Fetch(value = FetchMode.SUBSELECT)
#JoinColumn(name = "id", referencedColumnName = "id")
private List<CourseDao> course;
}
Course
#Entity
#Table(name = "course")
public class CourseDao {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#Column(name = "name")
private String name;
}
In my opinion it is bad rest design. I'll create POST endpoint with body, which contains array with course Id's and find students by course id's.
If the parameters are optional or an array you shouldn't use a path variable but use a request parameter.

Spring boot #OneToMany association saves id with null value

Hello guys i don't know why but when i tried to define an association
#one to many i get a null in the service_id and question_id.
first entity
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
#Inheritance(strategy = InheritanceType.JOINED)
public class Services implements Serializable{
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
private String serviceName;
private String description;
private String image;
#OneToMany(cascade = CascadeType.ALL)
private List<Questions> questions;
Second entity
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Questions implements Serializable {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
private String question;
#Column(name="service_id")
private String service_id;
#OneToMany(cascade = CascadeType.ALL)
private List<Answers> answers;
third entity
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Answers implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(nullable = false, updatable = false)
private Long id;
private String answer;
private double cost;
#Column(name="question_id")
private String question_id;
you can find the image for the tables bellow
enter image description here
All you need to do is remove the following line from Both of your models:
#Column(nullable = false, updatable = false)
After this line: #GeneratedValue(strategy = GenerationType.IDENTITY)
That will solve your problem.

Lazy loading is not working in OnetoMany Jpa relations

Below are my entity classes Instructor and Courses having OnetoMany Relations, where all CRUD Operation is working but while fetching Instructor I don't want courses to be fetched. But when I execute GET instructor By Id, It also fetches courses in Postman. This should be avoided.
public class Instructor {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
private String firstName;
private String lastName;
private String email;
#OneToMany(mappedBy = "instructor", cascade = {CascadeType.ALL})
#JsonManagedReference
private List < Course > courses;
}
public class Course {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
#ManyToOne(fetch =FetchType.LAZY)
#JoinColumn(name = "instructor_id")
#JsonBackReference
private Instructor instructor;
}

Spring Framework + Spring Data + Hibernate Jpa OneToMany child removal fails

I have an unidirectional OneToMany JPA entity mapping in my (Spring Framework + Spring Data + Hibernate JPA) project. Entity classes are like in the following code.(I have removed irrelevant class members for brevity).
#Entity
#Table(name = "employees")
class Employee{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
#JoinColumn(name = "employee_id")
private List<DepartmentAssignment> departmentAssignments = new ArrayList<>();
}
#Entity
#Table(name = "department_assignments")
class DepartmentAssignment{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
#NotNull
#Column(name = "employee_id")
private Integer employeeId;
#NotNull
#Column(name = "department_id")
private Integer departmentId;
}
#Entity
#Table(name = "departments")
class Department{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Integer id;
}
And, in one of my service classes have a method to remove a DepartmentAssignment from an Employee like below.
public Employee deleteDepartmentAssignment(Integer empId, Integer deptAssignmentId) {
Employee employee = employeeRepository.findOne(empId);
if(employee != null) {
for ( DepartmentAssignment da : employee.getDepartmentAssignments()) {
if(da.getId().equals(deptAssignmentId)) {
employee.getDepartmentAssignments().remove(da);
employee = employeeRepository.save(employee);
break;
}
}
}
return employee;
}
However, calling above methods gives me an error: org.hibernate.exception.ConstraintViolationException ,and in the SQL log, I can see Column 'employee_id' cannot be null error for the last SQL statement of the transaction.
Can anybody tell me what I'm doing wrong here and how to get it fixed?
You don't need to add
#NotNull
#Column(name = "employee_id")
private Integer employeeId;
to the Employee, if you use #JoinColumn(name = "employee_id"). Try to remove it.
You can try the following, not sure why you use the plain id in the object. Thats not object relational mapping.
For more details see Hibernate triggering constraint violations using orphanRemoval
#Entity
#Table(name = "employees")
class Employee{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "employee", orphanRemoval = true)
private List<DepartmentAssignment> departmentAssignments = new ArrayList<>();
}
#Entity
#Table(name = "department_assignments")
class DepartmentAssignment{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#ManyToOne(optional=false)
private Employee employee;
#ManyToOne(optional=false)
private Department department;
}
#Entity
#Table(name = "departments")
class Department{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
You must look .hbm.xml file and you should mapping your Entity in this file and
you can look this example
http://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example/
I hope it will be useful for you.
try removing
cascade = CascadeType.ALL
but im not 100% sure..

Resources