Deleting items from DB using hibernate - java

I have a table Teachers which is joined with the table Quiz. 1 Teacher can have N Quizes.
So, I want to be able to delete a teacher from the database.
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails
These are the Teacher and Quiz classes. I thought adding a delete cascade would solve it, but it didn't.
Teacher
#Entity
public class Teacher extends User{
private List<Quiz> quizList;
public Teacher() {
}
public Teacher(String name, String surname, String nick, String password) {
super(name, surname, nick, password);
quizList = new ArrayList<>();
}
#OneToMany
#Cascade(value={CascadeType.REMOVE})
#JoinColumn(name = "quiz_id")
public List<Quiz> getQuizList() {
return quizList;
}
public void setQuizList(List<Quiz> quizList) {
this.quizList = quizList;
}
}
Quiz
#Entity
public class Quiz {
private SimpleStringProperty name = new SimpleStringProperty();
private int quiz_id;
private List<Task> taskList;
private Teacher owner;
public Quiz() {
}
public Quiz(String name, Teacher owner) {
this.name.set(name);
this.owner = owner;
taskList = new ArrayList<>();
}
public Quiz(String name, Teacher owner, List<Task> taskList) {
this.name.set(name);
this.owner = owner;
this.taskList = taskList;
}
#Column(nullable = false)
public String getName() {
return name.get();
}
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
#ManyToOne
#JoinColumn(name = "teacher_id")
public Teacher getOwner() {
return owner;
}
public void setOwner(Teacher owner) {
this.owner = owner;
}
#Id
#GenericGenerator(name="id" , strategy="increment")
#GeneratedValue(generator="id")
public int getQuiz_id() {
return quiz_id;
}
public void setQuiz_id(int quiz_id) {
this.quiz_id = quiz_id;
}
#OneToMany
public List<Task> getTasksList() {
return taskList;
}
public void setTasksList(List<Task> taskList) {
this.taskList = taskList;
}
}
Any idea how I could solve it? I appreciate all answers and suggestions.
EDIT: Well, I managed to solve it, I just got a bit lost in all my annotations. Here's the working version now.
Teacher
#Entity
public class Teacher extends User{
private List<Quiz> quizList;
public Teacher() {
}
public Teacher(String name, String surname, String nick, String password) {
super(name, surname, nick, password);
quizList = new ArrayList<>();
}
#OneToMany(orphanRemoval = true)
public List<Quiz> getQuizList() {
return quizList;
}
public void setQuizList(List<Quiz> quizList) {
this.quizList = quizList;
}
}
Quiz
#Entity
public class Quiz {
private SimpleStringProperty name = new SimpleStringProperty();
private int quiz_id;
private List<Task> taskList;
public Quiz() {
}
public Quiz(String name) {
this.name.set(name);
taskList = new ArrayList<>();
}
public Quiz(String name , List<Task> taskList) {
this.name.set(name);
this.taskList = taskList;
}
#Column(nullable = false)
public String getName() {
return name.get();
}
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
#Id
#GenericGenerator(name="id" , strategy="increment")
#GeneratedValue(generator="id")
public int getQuiz_id() {
return quiz_id;
}
public void setQuiz_id(int quiz_id) {
this.quiz_id = quiz_id;
}
#OneToMany(orphanRemoval = true)
public List<Task> getTasksList() {
return taskList;
}
public void setTasksList(List<Task> taskList) {
this.taskList = taskList;
}
}

The parent:
#Entity
public class Teacher extends User{
private List<Quiz> quizList;
public Teacher() {
}
public Teacher(String name, String surname, String nick, String password) {
super(name, surname, nick, password);
quizList = new ArrayList<>();
}
#OneToMany(mappedBy = "teacher")
#Cascade(CascadeType.ALL)
public List<Quiz> getQuizList() {
return quizList;
}
public void setQuizList(List<Quiz> quizList) {
this.quizList = quizList;
}
}
The child:
#Entity
public class Quiz {
private SimpleStringProperty name = new SimpleStringProperty();
private int quiz_id;
private List<Task> taskList;
#ManyToOne
#Cascade(CascadeType.ALL)
#JoinColumn(name="teacher_id", nullable = false)
private Teacher owner;
public Quiz() {
}
public Quiz(String name, Teacher owner) {
this.name.set(name);
this.owner = owner;
taskList = new ArrayList<>();
}
public Quiz(String name, Teacher owner, List<Task> taskList) {
this.name.set(name);
this.owner = owner;
this.taskList = taskList;
}
#Column(nullable = false)
public String getName() {
return name.get();
}
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
public Teacher getOwner() {
return owner;
}
public void setOwner(Teacher owner) {
this.owner = owner;
}
#Id
#GenericGenerator(name="id" , strategy="increment")
#GeneratedValue(generator="id")
public int getQuiz_id() {
return quiz_id;
}
public void setQuiz_id(int quiz_id) {
this.quiz_id = quiz_id;
}
#OneToMany
public List<Task> getTasksList() {
return taskList;
}
public void setTasksList(List<Task> taskList) {
this.taskList = taskList;
}
}
It should help you.

Related

Going around the many-to-many relationship in Spring boot, but no new entity is created

I'm using spring boot to construct a database using AWS RDS as well. I want to track down how many stars a user gives to different products. I learnt to go around the many-to-many relationship by creating a table connecting two one-to-many other tables. For this reason, I have created the following tables:
When a user rates a product, an api is called through the put command in order to track down which user(uid) rates which product(pid). When the product(pid) is not rated by anyone, a rate_item is created that contains the pid and also the uid. However, when another user (with a different uid) rates the same product (same pid), the rate_item is updated, which is a problem becausse supposedly, a new row containing the same pid and a different uid should be created, as seen in the following (user with "uid 1" has already rated the same product and when user with "uid 2" rates the same product, the entity gets updated, but not like a new entity is created):
ProductEntity:
#Entity
#Table(name = "product")
public class ProductEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name = "pid",nullable = false)
private Integer pid;
#Column(name = "name", nullable = false)
private String name;
#Column(name="theme", nullable = false)
private String theme;
#Column(name="color", nullable = false)
private String color;
#Column(name="sizeZero", nullable = true)
private String sizeZero;
#Column(name="sizeOne", nullable = true)
private String sizeOne;
#Column(name="sizeTwo", nullable = true)
private String sizeTwo;
#Column(name="sizeThree", nullable = true)
private String sizeThree;
#Column(name="description",nullable = false)
private String description;
#Column(name = "image_url", nullable = false)
private String imageUrl;
#Column(name = "price",nullable = false)
private BigDecimal price;
#Column(name = "stock",nullable = false)
private Integer stock;
public ProductEntity(CreateProductData createProductData) {
this.pid = createProductData.getPid();
this.name = createProductData.getName();
this.theme =createProductData.getTheme();
this.color=createProductData.getColor();
this.sizeZero=createProductData.getSizeZero();
this.sizeOne =createProductData.getSizeOne();
this.sizeTwo =createProductData.getSizeTwo();
this.sizeThree =createProductData.getSizeThree();
this.description =createProductData.getDescription();
this.imageUrl = createProductData.getImageUrl();
this.price = createProductData.getPrice();
this.stock = createProductData.getStock();
}
public ProductEntity(){
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTheme() {
return theme;
}
public void setTheme(String productType) {
this.theme = productType;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getSizeZero() {
return sizeZero;
}
public void setSizeZero(String sizeZero) {
this.sizeZero = sizeZero;
}
public String getSizeOne() {
return sizeOne;
}
public void setSizeOne(String smallSize) {
this.sizeOne = smallSize;
}
public String getSizeTwo() {
return sizeTwo;
}
public void setSizeTwo(String mediumSize) {
this.sizeTwo = mediumSize;
}
public String getSizeThree() {
return sizeThree;
}
public void setSizeThree(String largeSize) {
this.sizeThree = largeSize;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
}
UserEntity:
#Entity
#Table(name="User")
public class UserEntity {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="uid",nullable = false)
private Integer uid;
#Column(name="username", nullable = false)
private String username;
#Column(name="email", nullable = false, unique = true)
private String email;
#Column(name="password", nullable = false)
private String password;
#Column(name = "firebase_uid", nullable = false)
private String firebaseUid;
#Column(name= "emailVerified", nullable = false,columnDefinition = "boolean default false")
private Boolean emailVerified=false;
#Column(name="subscribed", nullable = false)
private Boolean subscribed;
public UserEntity(UserEntity tempUserEntity){
this.uid=tempUserEntity.getUid();
this.firebaseUid=tempUserEntity.getFirebaseUid();
this.email=tempUserEntity.getEmail();
}
public UserEntity(CreateFirebaseUserData createFirebaseUserData){
this.username=createFirebaseUserData.getUsername();
this.email=createFirebaseUserData.getEmail();
this.password=createFirebaseUserData.getPassword();
this.firebaseUid= createFirebaseUserData.getFirebaseUid();
this.subscribed=createFirebaseUserData.getSubscribed();
}
public UserEntity(){
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFirebaseUid() {
return firebaseUid;
}
public void setFirebaseUid(String firebaseUid) {
this.firebaseUid = firebaseUid;
}
public Boolean getEmailVerified() {
return emailVerified;
}
public void setEmailVerified(Boolean emailVerified) {
this.emailVerified = emailVerified;
}
public Boolean getSubscribed() {
return subscribed;
}
public void setSubscribed(Boolean subscribed) {
this.subscribed = subscribed;
}
}
RatingEntity:
#Entity
#Table(name="Rating")
public class ProductsRatedByUserEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="pruid")
private Integer pruid;
#OneToOne
#JoinColumn(name="pid",nullable = false)
private ProductEntity product;
#ManyToOne
#JoinColumn(name="uid",nullable = false)
private UserEntity user;
#Column
private Integer starsGiven;
#Column(name="total_stars", nullable = false)
private Integer totalStars;
#Column(name="total_num_of_users_who_rated", nullable = false)
private Integer totalNumOfUsersWhoRated;
#Column(name="average_stars")
private BigDecimal averageStars;
public ProductsRatedByUserEntity(UserEntity userEntity, ProductEntity productEntity, Integer numOfStars){
this.product=productEntity;
this.user=userEntity;
this.starsGiven=numOfStars;
this.totalStars=numOfStars;
this.totalNumOfUsersWhoRated=1;
this.averageStars=BigDecimal.valueOf(this.getTotalStars()).divide(BigDecimal.valueOf(this.getTotalNumOfUsersWhoRated()));
}
public ProductsRatedByUserEntity(ProductEntity product,UserEntity user,Integer numOfStars,Integer newTotalNumOfStars, Integer newTotalNumberOfUsers, BigDecimal averageStars){
this.product=product;
this.user=user;
this.starsGiven=numOfStars;
this.totalStars=newTotalNumOfStars;
this.totalNumOfUsersWhoRated=newTotalNumberOfUsers;
this.averageStars=averageStars;
}
public ProductsRatedByUserEntity(){
}
public Integer getPruid() {
return pruid;
}
public void setPruid(Integer plbuid) {
this.pruid = plbuid;
}
public ProductEntity getProduct() {
return product;
}
public void setProduct(ProductEntity product) {
this.product = product;
}
public UserEntity getUser() {
return user;
}
public void setUser(UserEntity user) {
this.user = user;
}
public Integer getStarsGiven() {
return starsGiven;
}
public void setStarsGiven(Integer starsGiven) {
this.starsGiven = starsGiven;
}
public Integer getTotalStars() {
return totalStars;
}
public void setTotalStars(Integer totalStars) {
this.totalStars = totalStars;
}
public Integer getTotalNumOfUsersWhoRated() {
return totalNumOfUsersWhoRated;
}
public void setTotalNumOfUsersWhoRated(Integer totalNumOfUsersWhoLiked) {
this.totalNumOfUsersWhoRated = totalNumOfUsersWhoLiked;
}
public BigDecimal getAverageStars() {
return averageStars;
}
public void setAverageStars(BigDecimal averageStars) {
this.averageStars = averageStars;
}
}
Api:
#CrossOrigin
#RestController
public class ProductApi {
private ProductService productService;
private ProductsRatedByUserService productsRatedByUserService;
#Autowired
public ProductApi(ProductService productService,ProductsRatedByUserService productsRatedByUserService){
this.productService=productService;
this.productsRatedByUserService=productsRatedByUserService;
}
#PutMapping("/product/rating/{pid}/{numOfStars}")
public ProductsRatedByUserResponseDto updateRating(#PathVariable Integer pid, #PathVariable Integer numOfStars, JwtAuthenticationToken jwtAuthenticationToken) throws ProductFoundByIdException {
FirebaseUserData firebaseUserData=new FirebaseUserData(jwtAuthenticationToken);
ProductsRatedByUserDetail productsRatedByUserDetail=productsRatedByUserService.updateProductRating(pid,numOfStars,firebaseUserData);
return new ProductsRatedByUserResponseDto(productsRatedByUserDetail);
}
}
RatingServiceImpl:
#Service
#Component
public class ProductsRatedByUserServiceImpl implements ProductsRatedByUserService {
public ProductsRatedByUserRepository productsRatedByUserRepository;
public ProductRepository productRepository;
public UserRepository userRepository;
#Autowired
public ProductsRatedByUserServiceImpl(ProductsRatedByUserRepository productsRatedByUserRepository,ProductRepository productRepository,UserRepository userRepository){
this.productsRatedByUserRepository=productsRatedByUserRepository;
this.productRepository=productRepository;
this.userRepository=userRepository;
}
#Override
public ProductsRatedByUserDetail updateProductRating(Integer pid, Integer numOfStars, FirebaseUserData firebaseUserData) throws ProductFoundByIdException {
if(!productRepository.existsById(pid)){
throw new ProductFoundByIdException();
}
UserEntity userEntity=userRepository.findUserEntityByEmail(firebaseUserData.getEmail());
ProductEntity productEntity =productRepository.findById(pid).orElse(null);
//check if the product has been rated by *any user*
//If no, we need to create an entity
if(!productsRatedByUserRepository.existsByProduct(productEntity)){
ProductsRatedByUserEntity productsRatedByUserEntity=new ProductsRatedByUserEntity(userEntity, productEntity, numOfStars);
ProductsRatedByUserEntity productsRatedByUserEntityReturned=productsRatedByUserRepository.save(productsRatedByUserEntity);
System.out.println("the product has been rated by *any user*");
return new ProductsRatedByUserDetail(productsRatedByUserEntityReturned);
}
//If yes, we update the entity from there
else {
//if the product has been rated by this very user
if (productsRatedByUserRepository.existsByUserAndProduct(userEntity, productEntity)) {
ProductsRatedByUserEntity productsRatedByUserEntity = productsRatedByUserRepository.findTopByUserAndProduct(userEntity, productEntity);
productsRatedByUserEntity.setTotalStars(productsRatedByUserEntity.getTotalStars() - productsRatedByUserEntity.getStarsGiven() + numOfStars);
productsRatedByUserEntity.setStarsGiven(numOfStars);
productsRatedByUserEntity.setAverageStars(BigDecimal.valueOf(productsRatedByUserEntity.getTotalStars()).divide(BigDecimal.valueOf(productsRatedByUserEntity.getTotalNumOfUsersWhoRated())));
ProductsRatedByUserEntity productsRatedByUserEntityReturned = productsRatedByUserRepository.save(productsRatedByUserEntity);
System.out.println("the product has been rated by this very user");
return new ProductsRatedByUserDetail(productsRatedByUserEntityReturned);
} else {
//The product has not been rated by this very user
ProductsRatedByUserEntity productsRatedByUserEntity = productsRatedByUserRepository.findTopByProduct(productEntity);
int newTotalNumOfStars = (productsRatedByUserEntity.getTotalStars() + numOfStars);
int newTotalNumberOfUsers = productsRatedByUserEntity.getTotalNumOfUsersWhoRated() + 1;
productsRatedByUserEntity.setUser(userEntity);
System.out.println("The product has not been rated by this very user");
return new ProductsRatedByUserDetail(productsRatedByUserRepository.save(new ProductsRatedByUserEntity(productEntity, userEntity, numOfStars, newTotalNumOfStars, newTotalNumberOfUsers, BigDecimal.valueOf(newTotalNumOfStars).divide(BigDecimal.valueOf(newTotalNumberOfUsers)))));
}
}
}
}
RatingServiceInterface:
public interface ProductsRatedByUserService {
ProductsRatedByUserDetail updateProductRating(Integer pid, Integer numOfStars, FirebaseUserData firebaseUserData) throws ProductFoundByIdException;
}
Repository:
public interface ProductsRatedByUserRepository extends CrudRepository<ProductsRatedByUserEntity,Integer> {
boolean existsByProduct(ProductEntity product);
ProductsRatedByUserEntity findTopByProduct(ProductEntity product);
boolean existsByUserAndProduct(UserEntity userEntity, ProductEntity product);
ProductsRatedByUserEntity findTopByUserAndProduct(UserEntity userEntity, ProductEntity product);
}
I will really appreciate anyone who can help me with this! I've been stuck for a whole day! I don't want to use the many-to-many annotation because it seems a bit messy. Thanks!
I have found the mistake. In my RatingEntity code, the getter and setter are erroneous. There's some typos there. It should be
public Integer getPruid() {
return pruid;
}
public void setPruid(Integer pruid) {
this.pruid = pruid;
}

ids for this class must be manually assigned before calling save(): com.employeesService.EmployeesService.model.Employee

I have a manyToMany relationship between Department and Employee
Image of Employee schema
My problem came after i changed the composited keys to an Embeddable class and then calling that class as an Id on my DepartmentEmployee class
These are my classes:
DepartmentEmployeeId:
#Embeddable
public class DepartmentEmployeeId implements Serializable {
#Column(name = "dept_no")
private String deptNo;
#Column(name = "emp_no")
private Long empNo;
public DepartmentEmployeeId() {
}
public DepartmentEmployeeId(String deptNo, Long empNo) {
this.deptNo = deptNo;
this.empNo = empNo;
}
public String getDeptNo() {
return deptNo;
}
public void setDeptNo(String deptNo) {
this.deptNo = deptNo;
}
public Long getEmpNo() {
return empNo;
}
public void setEmpNo(Long empNo) {
this.empNo = empNo;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
DepartmentEmployeeId that = (DepartmentEmployeeId) o;
return Objects.equals(deptNo, that.deptNo) &&
Objects.equals(empNo, that.empNo);
}
#Override
public int hashCode() {
return Objects.hash(deptNo, empNo);
}
}
Department:
#Entity
#Table(name = "departments")
public class Department {
#Id
#Column(name = "dept_no")
private String deptNo;
#Column(name = "dept_name")
private String deptName;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "department", orphanRemoval = true)
#JsonIgnore
private List<DepartmentEmployee> departmentEmployees = new ArrayList<>();
public String getDeptNo() {
return deptNo;
}
public void setDeptNo(String deptNo) {
this.deptNo = deptNo;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public void addEmployee(DepartmentEmployee departmentEmployee) {
Employee employee=new Employee();
departmentEmployee = new DepartmentEmployee(this, employee);
departmentEmployees.add(departmentEmployee);
}
public List<DepartmentEmployee> getDepartmentEmployees() {
return departmentEmployees;
}
}
Employee:
#Entity
#Table(name = "employees")
public class Employee {
public enum Gender {M, F}
#Id
private Long empNo;
#Column(name = "birth_date")
private LocalDate birthDate;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Enumerated(EnumType.STRING)
#Column(name = "gender")
private Gender gender;
#Column(name = "hire_date")
private LocalDate hireDate;
#OneToMany(cascade = CascadeType.ALL)
#JoinColumn(name = "emp_no")
#JsonIgnore
private List<Salary> salaries = new ArrayList<>();
#OneToMany(cascade = CascadeType.ALL, mappedBy = "employee",orphanRemoval = true)
#JsonIgnore
private List<DepartmentEmployee> departmentEmployees = new ArrayList<>();
public List<Salary> getSalaries() {
return salaries;
}
public Long getEmpNo() {
return empNo;
}
public void setEmpNo(Long empNo) {
this.empNo = empNo;
}
public LocalDate getBirthDate() {
return birthDate;
}
public void setBirthDate(LocalDate birthDate) {
this.birthDate = birthDate;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public LocalDate getHireDate() {
return hireDate;
}
public void setHireDate(LocalDate hireDate) {
this.hireDate = hireDate;
}
public void assignSalary(Salary salary) {
salaries.add(salary);
}
public List<DepartmentEmployee> getDepartmentEmployees() {
return departmentEmployees;
}
}
Department Employee
#Entity
#Table(name = "dept_emp")
public class DepartmentEmployee {
#EmbeddedId
private DepartmentEmployeeId id;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("deptNo")
private Department department;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("empNo")
private Employee employee;
#Column(name = "from_date")
private LocalDate fromDate;
#Column(name = "to_date")
private LocalDate toDate;
public DepartmentEmployee() {
}
public DepartmentEmployee(Department department, Employee employee) {
this.department=department;
this.employee=employee;
this.id = new DepartmentEmployeeId(department.getDeptNo(), employee.getEmpNo());
}
public DepartmentEmployeeId getId() {
return id;
}
public void setId(DepartmentEmployeeId id) {
this.id = id;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public LocalDate getFromDate() {
return fromDate;
}
public void setFromDate(LocalDate fromDate) {
this.fromDate = fromDate;
}
public LocalDate getToDate() {
return toDate;
}
public void setToDate(LocalDate toDate) {
this.toDate = toDate;
}
}
My Service add method:
#Override
#Transactional
public Employee addEmployeeToDepartment(String deptNo, Long empNo, DepartmentEmployee departmentEmployee) {
Department department = this.departmentRepository.findById(deptNo).orElseThrow(() -> new DepartmentNotFoundException(deptNo));
Employee employee = this.employeeRepository.findById(empNo).orElseThrow(() -> new EmployeeNotFoundException(empNo));
departmentEmployee.setId(new DepartmentEmployeeId(department.getDeptNo(), employee.getEmpNo()));
departmentEmployee.setDepartment(department);
departmentEmployee.setEmployee(employee);
department.addEmployee(departmentEmployee);
this.departmentRepository.save(department);
return employee;
}
I found my problem, it was at this method:
public void addEmployee(DepartmentEmployee departmentEmployee) {
Employee employee=new Employee();
departmentEmployee = new DepartmentEmployee(this, employee);
departmentEmployees.add(departmentEmployee);
}
I was creating a new employee and i was not giving it an id, this is all i had to do:
public void addEmployee(DepartmentEmployee departmentEmployee) {
departmentEmployees.add(departmentEmployee);
}
Its very simple ...
In the Employee class you have
#Entity
#Table(name = "employees")
public class Employee {
public enum Gender {M, F}
#Id
//Add #GenerateValue here
private Long empNo;
You are missing a #GeneratedValue annotation just below the #Id.
For more details see here.

Not able to retrive data from Crud Operation in Hibernate

I have a application written in Spring, Hibernate and SpringBoot,
I have 2 entities class with one to many mapping,
Here are my LeadUserDb entity class
#Entity
#Table(name="lead_user_db")
#NamedQuery(name="LeadUserDb.findAll", query="SELECT l FROM LeadUserDb l")
public class LeadUserDb implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
#Column(name="branchcode")
private String branchcode;
#Column(name="reporting_level")
private int reportingLevel;
//bi-directional many-to-one association to UserBasicDetailsDb
#ManyToOne
#JoinColumn(name="email_Id")
private UserBasicDetailsDb userBasicDetailsDb;
public LeadUserDb() {
}
public String getBranchcode() {
return this.branchcode;
}
public void setBranchcode(String branchcode) {
this.branchcode = branchcode;
}
public int getReportingLevel() {
return this.reportingLevel;
}
public void setReportingLevel(int reportingLevel) {
this.reportingLevel = reportingLevel;
}
public UserBasicDetailsDb getUserBasicDetailsDb() {
return this.userBasicDetailsDb;
}
public void setUserBasicDetailsDb(UserBasicDetailsDb userBasicDetailsDb) {
this.userBasicDetailsDb = userBasicDetailsDb;
}
And This is my UserBasicDetailsDb Entity Class
#Entity
#Table(name="user_basic_details_db")
public class UserBasicDetailsDb implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String email;
private String address;
private String city;
private String dob;
private String mobile;
private String name;
private String pan;
private String pincode;
private String state;
#OneToMany(mappedBy="userBasicDetailsDb")
private List<LeadUserDb> leadUserDbs;
public UserBasicDetailsDb() {
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getDob() {
return this.dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getMobile() {
return this.mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getPan() {
return this.pan;
}
public void setPan(String pan) {
this.pan = pan;
}
public String getPincode() {
return this.pincode;
}
public void setPincode(String pincode) {
this.pincode = pincode;
}
public String getState() {
return this.state;
}
public void setState(String state) {
this.state = state;
}
public List<LeadUserDb> getLeadUserDbs() {
return this.leadUserDbs;
}
public void setLeadUserDbs(List<LeadUserDb> leadUserDbs) {
this.leadUserDbs = leadUserDbs;
}
public LeadUserDb addLeadUserDb(LeadUserDb leadUserDb) {
getLeadUserDbs().add(leadUserDb);
leadUserDb.setUserBasicDetailsDb(this);
return leadUserDb;
}
public LeadUserDb removeLeadUserDb(LeadUserDb leadUserDb) {
getLeadUserDbs().remove(leadUserDb);
leadUserDb.setUserBasicDetailsDb(null);
return leadUserDb;
}
what i want to achieve is to create a query like this one
SELECT a.branchcode as branchCode,b.name FROM lead_user_db a
inner join user_basic_details_db b
where b.email = a.email_id and a.reporting_level = 3
here is what I have written my Repository class
public interface GetUserList extends CrudRepository<LeadUserDb, Integer> {
#Query(value = "SELECT a.id, a.branchcode as branchCode,b.name as name,a.reporting_level,a.email_id FROM lead_user_db a\n" +
"inner join user_basic_details_db b\n" +
"where b.email = a.email_id and a.reporting_level = ?1", nativeQuery = true)
List<LeadUserDb> findByReportingLevel(int reportingLevel);
}
and this is how I am calling it
UserBasicDetailsDb details = GetUserList.findByReportingLevel(3);
NOTE
Getting a new error Cannot determine value type from string test#dev.com
I am getting a hell lot of data, and the actual output have only 2 records
My question is how can i fetch the list of user based on reportingLevel
Any help would be appreciated

OneToOne Bi-Directional Mapping using Hibernate annotation

I want a Bi-Directional mapping on my 2 Entities(PersonDetail,
PassportDetail) but it seems that it doesn't work fine. I want that
PersonDetail has a PassportId and PassportDetail has a PersonId as well.
My PersonDetail java Code
#Entity
#Table(name="persondetail")
public class PersonDetail {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="person_id")
private int id;
#Column(name="person_name")
private String name;
#Column(name="person_phone")
private long phone;
#OneToOne(mappedBy="person",cascade=CascadeType.ALL)
#JoinColumn(name="passport_id")
private PassportDetail passport;
public PassportDetail getPassport() {
return passport;
}
public void setPassport(PassportDetail passport) {
this.passport = passport;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getPhone() {
return phone;
}
public void setPhone(long phone) {
this.phone = phone;
}
#Column(name="passport_id")
private int passort_id;
public int getPassort_id() {
return passort_id;
}
public void setPassort_id(int passort_id) {
this.passort_id = passort_id;
}
}
Here is my PassportDetail Java Code
#Entity
#Table(name="PassportDetail")
public class PassportDetail {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="passport_id")
private int id;
#Column(name="passport_number")
private String passportNumber;
#Column(name="country_name")
private String country;
#Column(name="issue_date")
#Temporal(TemporalType.DATE)
private Date date;
#OneToOne
#JoinColumn(name="person_id")
private PersonDetail person;
public String getPassportNumber() {
return passportNumber;
}
public void setPassportNumber(String passportNumber) {
this.passportNumber = passportNumber;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public PersonDetail getPerson() {
return person;
}
public void setPerson(PersonDetail person) {
this.person = person;
}
}
Here is the Output in MySql
Here is the Output of Both table as you can clearly see the problem i.e PersonDetail has a column named passport_id but it dosesn't have any value
Here is the insertion code
public class MappingMain {
public static void main(String[] args) {
PersonDetail person=new PersonDetail();
PassportDetail passport = new PassportDetail();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd");
person.setName("Ankit");
person.setPhone(790148565);
passport.setCountry("india");
try {
passport.setDate(sdf.parse("2018-04-15"));
}
catch(Exception e)
{
}
passport.setPassportNumber("QUJMZ123");
passport.setPerson(person);
person.setPassport(passport);
PersonDao dao=new PersonDao();
dao.save(person);
}
Here is the DAO class
public class MappingDao {
SessionFactory sf=Util.getSessionFactory();
public void save(UserDemo user)
{
Session session=sf.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
}
}

Why is my Spring data JPA's query not fetching distinct rows?

I have the following entity
public class Attendance extends AbstractEntity<Long>{
/**
*
*/
private static final long serialVersionUID = -1409043060497488674L;
#ManyToOne
private Student student;
#ManyToOne
private Staff staff;
#ManyToOne
private Teacher teacher;
private UserType userType;
private Timestamp checkInTime;
private String cardNumber;
#ManyToOne
private School school;
private AttendanceStatus status;
private AttendanceSource source;
#ManyToOne
private User markedBy;
#Transient
private long dummyId;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Staff getStaff() {
return staff;
}
public void setStaff(Staff staff) {
this.staff = staff;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public UserType getUserType() {
return userType;
}
public void setUserType(UserType userType) {
this.userType = userType;
}
public Timestamp getCheckInTime() {
return checkInTime;
}
public void setCheckInTime(Timestamp checkInTime) {
this.checkInTime = checkInTime;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
public AttendanceStatus getStatus() {
return status;
}
public void setStatus(AttendanceStatus status) {
this.status = status;
}
public User getMarkedBy() {
return markedBy;
}
public void setMarkedBy(User markedBy) {
this.markedBy = markedBy;
}
public AttendanceSource getSource() {
return source;
}
public void setSource(AttendanceSource source) {
this.source = source;
}
public long getDummyId() {
return dummyId;
}
public void setDummyId(long dummyId) {
this.dummyId = dummyId;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
}
I am trying to fetch distinct rows of this tables using the following query:
#Query("Select distinct a.cardNumber, a.student, a.checkInTime, a.status, a.source, a.userType from Attendance a where a.school.schoolUrl=?1 and a.userType=?2 and a.status=?3 and a.checkInTime>=?4 order by a.checkInTime desc")
List<Object[]> getTodaysStudentAttendance(String schoolUrl,UserType userType,AttendanceStatus status,Timestamp timestamp);
However no matter what I do I just cant fetch the distinct rows. I have the following data in my data base
The query is returning all these three rows. What exactly am I missing? Please help.

Categories

Resources