I am getting very weird problem when trying to update the record in database .Main Node is updating properly but Relationship not creating after deleting it.
I have Node with relationship in database i am trying to update it via this code
Role roleRecord = findByUuid(uuid);//Get Role Record
Role roleData = new Role();//Create a new role object and update values
roleData.setDescription(role.getDescription());
roleData.setUuid(roleRecord.getUuid());
roleData.setRoleName(roleRecord.getRoleName());
roleData.setLabels(updatedLabelRecord);
deleteRole(roleRecord);// Delete existing role from database
for (Labels label : dbRecord) { //Delete relationship Node
deleteLabel(label);
}
createRole(roleData);// Then Create role and Label with new Data set
This code creating Role record but not the Label Node(Which is a relationship),Relationship something like this
Role->FILTERS_ON->Label
EDIT 1-
Role is a Neo4j Entity
deleteRole is method
public void deleteRole(Role roleEntity) {
roleRepository.delete(roleEntity);
}
deleteLabel is a method
public void deleteLabel(com.nokia.nsw.uiv.uam.entities.Labels label) {
labelRepository.delete(label);
}
createRole is a method
public Role createRole(Role role) {
return roleRepository.save(role);
}
EDIT 2 -
Role Entity Class
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.Api;
#Api(
tags = "Role",
description = ""
)
#NodeEntity(label = "com.model.Role")
public class Role implements Serializable {
private static final long serialVersionUID = -8010543109475083169L;
private String roleName = null;
private String description = null;
// #Relationship(type = "HAS_ROLE", direction="INCOMING")
// private Tenant tenant;
#Relationship(type = "FILTERS_ON")
private List<Labels> labels = new ArrayList<>();
#JsonIgnore
private Long id;
#Id
#GeneratedValue(strategy = UivUuidStrategy.class)
#JsonProperty("id")
private String uuid;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
// public Tenant getTenant() {
// return tenant;
// }
//
// public void setTenant(Tenant tenant) {
// this.tenant = tenant;
// }
public List<Labels> getLabels() {
return labels;
}
public void setLabels(List<Labels> labels) {
this.labels = labels;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Label Entity class
import java.io.Serializable;
import java.util.Map;
import java.util.Objects;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Properties;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
#NodeEntity(label = "com.model.role.Filter")
public class Labels implements Serializable {
private static final long serialVersionUID = 1L;
private String labelName;
#Properties
private Map<String, String> match;
private String access;
#JsonIgnore
private Long id;
#Id
#GeneratedValue(strategy = UivUuidStrategy.class)
#JsonProperty("id")
private String uuid;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public Map<String, String> getMatch() {
return match;
}
public void setMatch(Map<String, String> match) {
this.match = match;
}
public String getLabelName() {
return labelName;
}
public void setLabelName(String labelName) {
this.labelName = labelName;
}
public String getAccess() {
return access;
}
public void setAccess(String access) {
this.access = access;
}
#Override
public String toString() {
return "labelName : " + this.labelName;
}
#Override
public boolean equals(Object obj) {
return (obj instanceof Labels) && this.labelName.equals(((Labels) obj).getLabelName());
}
#Override
public int hashCode() {
return Objects.hash(labelName);
}
}
Related
I am creating a crud api with a many to many relationship betwen role and user. When i make a Get HTTP Request, i get the mesage below but When i delete all relationship and make findall on single table, it works percfecttly. Where do you think the problem is?
Error Message in postman
{
"timestamp": "2021-07-10T04:28:24.877+0000",
"status": 500,
"error": "Internal Server Error",
"message": "JSON mapping problem: java.util.ArrayList[0]->com.notyfyd.entity.User[\"roles\"]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: com.notyfyd.entity.User.roles, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->com.notyfyd.entity.User[\"roles\"])",
"path": "/user/all"
}
Role Entity
package com.notyfyd.entity;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import javax.persistence.*;
import java.util.List;
#Entity
#Table(name = "t_role")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
#ManyToMany(targetEntity = User.class, mappedBy = "roles", cascade = {CascadeType.PERSIST, CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH})
private List<User> users;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
}
User Entity
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import javax.persistence.*;
import java.util.List;
#Entity
#Table(name = "t_user")
#JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private String mobile;
#Column(unique = true)
private String email;
#ManyToMany(targetEntity = Role.class, cascade = {CascadeType.PERSIST, CascadeType.DETACH,CascadeType.MERGE,CascadeType.REFRESH} )
#JoinTable(
name="t_user_roles",
joinColumns=
#JoinColumn( name="user_id", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="role_id", referencedColumnName="id"))
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
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 String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
here is the log error on MSSQL Server
2021-07-10 11:20:59.333 WARN 3124 --- [nio-6120-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: fdsa.edu.PNUFDSA.Model.AnneeAcademique.paiements, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: fdsa.edu.PNUFDSA.Model.AnneeAcademique.paiements, could not initialize proxy - no Session (through reference chain: java.util.ArrayList[0]->fdsa.edu.PNUFDSA.Model.AnneeAcademique["paiements"])]
the Entity is:
* "Visual Paradigm: DO NOT MODIFY THIS FILE!"
*
* This is an automatic generated file. It will be regenerated every time
* you generate persistence class.
*
* Modifying its content may cause the program not work, or your work may lost.
*/
/**
* Licensee:
* License Type: Evaluation
*/
package fdsa.edu.PNUFDSA.Model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
#Entity
#Data
//#org.hibernate.annotations.Proxy(lazy=false)
#Table(name="AnneeAcademique")
public class AnneeAcademique implements Serializable {
public AnneeAcademique() {
}
#Column(name="ID", nullable=false, length=10)
#Id
#GeneratedValue(generator="PNU_ANNEEACADEMIQUE_ID_GENERATOR")
#org.hibernate.annotations.GenericGenerator(name="PNU_ANNEEACADEMIQUE_ID_GENERATOR", strategy="native")
private int id;
#Column(name="Debut", nullable=true)
#Temporal(TemporalType.DATE)
private java.util.Date debut;
#Column(name="Fin", nullable=true)
#Temporal(TemporalType.DATE)
private java.util.Date fin;
#JsonIgnore
#ManyToMany(mappedBy="anneeAcademiques", targetEntity=fdsa.edu.PNUFDSA.Model.Cours.class)
#org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
#org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)
private java.util.Set cours = new java.util.HashSet();
#JsonIgnore
#OneToMany(mappedBy="anneeAcademique", targetEntity=fdsa.edu.PNUFDSA.Model.Paiement.class)
#org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
#org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)
private List paiements = new ArrayList();
private void setId(int value) {
this.id = value;
}
public int getId() {
return id;
}
public int getORMID() {
return getId();
}
public void setDebut(java.util.Date value) {
this.debut = value;
}
public java.util.Date getDebut() {
return debut;
}
public void setFin(java.util.Date value) {
this.fin = value;
}
public java.util.Date getFin() {
return fin;
}
public void setCours(java.util.Set value) {
this.cours = value;
}
public java.util.Set getCours() {
return cours;
}
public void setPaiements(List value) {
this.paiements = value;
}
public List getPaiements() {
return paiements;
}
public String toString() {
return String.valueOf(getId());
}
}
Are you returning that entity directly as json. Can add #JsonIgnore on below field.
#JsonIgnore
private List<Role> roles;
You can set fetch type to FetchType.EAGER on your many to many relations in your entities.
Try this and let me know what happened.
When I check an entities contents right after saving it, everything appears normal, but any other time and the mapped entities in it are all null. Both checks are done by getting it through its repository.
Ad
package com.stevan.madsapp.entities;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.jws.soap.SOAPBinding;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
#Entity(name = "ad")
#NamedStoredProcedureQuery(
name = "ad.getAds",
procedureName = "get_ads",
parameters = { #StoredProcedureParameter(mode = ParameterMode.IN, name = "param1", type = String.class) }
)
public class Ad {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(name = "name", nullable = false)
private String name;
#OneToMany(mappedBy = "ad")
private List<Question> questions = new ArrayList<>();
#ManyToOne
#JoinColumn(name = "author")
private UserDetails author;
#ManyToMany
#JoinTable(
name = "user_details_ad",
joinColumns = #JoinColumn(name = "user_details_id"),
inverseJoinColumns = #JoinColumn(name = "ad_id")
)
private Set<UserDetails> usersFinished = new HashSet<>();
#ManyToOne
#JoinColumn(name = "country")
private Country country;
#ManyToOne
#JoinColumn(name = "job")
private Job job;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Question> getQuestions() {
return questions;
}
public void setQuestions(List<Question> questions) {
this.questions = questions;
}
public UserDetails getAuthor() {
return author;
}
public void setAuthor(UserDetails author) {
this.author = author;
}
public Set<UserDetails> getUsersFinished() {
return usersFinished;
}
public void setUsersFinished(Set<UserDetails> usersFinished) {
this.usersFinished = usersFinished;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public Job getJob() {
return job;
}
public void setJob(Job job) {
this.job = job;
}
}
Question
package com.stevan.madsapp.entities;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#Entity(name = "question")
public class Question {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
#Column(nullable = false)
private String type;
#Column(nullable = false)
private String question;
#OneToMany(mappedBy = "question")
private List<McOption> radioOptions = new ArrayList<>();
#OneToMany(mappedBy = "question")
private List<McOption> checkboxOptions = new ArrayList<>();
#ManyToOne
#JoinColumn(name = "ad_id")
private Ad ad;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public List<McOption> getRadioOptions() {
return radioOptions;
}
public void setRadioOptions(List<McOption> radioOptions) {
this.radioOptions = radioOptions;
}
public List<McOption> getCheckboxOptions() {
return checkboxOptions;
}
public void setCheckboxOptions(List<McOption> checkboxOptions) {
this.checkboxOptions = checkboxOptions;
}
}
AdService
package com.stevan.madsapp.services;
import com.stevan.madsapp.entities.*;
import com.stevan.madsapp.repositories.AdRepository;
import com.stevan.madsapp.security.components.TokenIdCheck;
import com.stevan.madsapp.web.dto.AdDTO;
import com.stevan.madsapp.web.dto.QuestionDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.persistence.criteria.CriteriaBuilder;
import java.util.*;
#Service
public class AdService {
#Autowired
private AdRepository adRepository;
#Autowired
private QuestionService questionService;
#Autowired
private JobService jobService;
#Autowired
private CountryService countryService;
#Autowired
private UserDetailsService userDetailsService;
public List<AdDTO> getAds(Integer id)
{
UserDetails user = userDetailsService.getUserDetails(id);
Job job = user.getJob();
Country country = user.getCountry();
List<Ad> jobAds = job.getAds();
List<Ad> countryAds = country.getAds();
List<Ad> commonAds = new ArrayList<Ad>(jobAds);
commonAds.retainAll(countryAds);
return convertListToDTO(commonAds);
}
public Ad store(AdDTO ad, Integer id) {
Ad newAd = new Ad();
newAd.setName(ad.getName());
List<Question> newQuestions = new ArrayList<>();
for(Question question : ad.getQuestions())
{
Question newQuestion = questionService.store(question);
newQuestions.add(newQuestion);
}
newAd.setQuestions(newQuestions);
newAd.setAuthor(userDetailsService.getUserDetails(id));
newAd.setJob(jobService.getJob(ad.getJobId()));
newAd.setCountry(countryService.getCountry(ad.getCountryId()));
adRepository.save(newAd);
System.out.println(adRepository.getById(newAd.getId()).getQuestions());
return newAd;
}
public Ad getAd(Integer id)
{
return adRepository.getById(id);
}
public AdDTO requestAd(Integer adId, Integer userId)
{
Ad ad = getAd(adId);
UserDetails user = userDetailsService.getUserDetails(userId);
if(ad.getJob() != user.getJob() || ad.getCountry() != user.getCountry())
{
return null;
}
return convertToDTO(ad);
}
public List<AdDTO> convertListToDTO(List<Ad> ads)
{
List<AdDTO> adDTOS = new ArrayList<>();
for(Ad ad: ads)
{
AdDTO newAdDTO = convertToDTO(ad);
adDTOS.add(newAdDTO);
}
return adDTOS;
}
public AdDTO convertToDTO(Ad ad)
{
AdDTO newAdDTO = new AdDTO();
newAdDTO.setId(ad.getId());
newAdDTO.setName(ad.getName());
newAdDTO.setQuestions(ad.getQuestions());
newAdDTO.setJobId(ad.getJob().getId());
newAdDTO.setCountryId(ad.getCountry().getId());
return newAdDTO;
}
}
QuestionService
package com.stevan.madsapp.services;
import com.stevan.madsapp.entities.Ad;
import com.stevan.madsapp.entities.McOption;
import com.stevan.madsapp.entities.Question;
import com.stevan.madsapp.repositories.QuestionRepository;
import com.stevan.madsapp.web.dto.McOptionDTO;
import com.stevan.madsapp.web.dto.QuestionDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
#Service
public class QuestionService {
#Autowired
private QuestionRepository questionRepository;
#Autowired
private McOptionService mcOptionService;
public Question store(Question question)
{
Question newQuestion = new Question();
newQuestion.setQuestion(question.getQuestion());
newQuestion.setType(question.getType());
if (newQuestion.getType().equals("radio"))
{
List<McOption> newMcOptions = new ArrayList<>();
for (McOption mcOption : question.getRadioOptions())
{
McOption newMcOption = mcOptionService.store(mcOption);
newMcOptions.add(newMcOption);
}
newQuestion.setRadioOptions(newMcOptions);
}
else if(newQuestion.getType().equals("checkbox"))
{
List<McOption> newMcOptions = new ArrayList<McOption>();
for (McOption mcOption : question.getCheckboxOptions())
{
McOption newMcOption = mcOptionService.store(mcOption);
newMcOptions.add(newMcOption);
}
newQuestion.setCheckboxOptions(newMcOptions);
}
questionRepository.save(newQuestion);
return newQuestion;
}
}
(This one just in case I missed something)
AdController
package com.stevan.madsapp.web.controllers;
import com.stevan.madsapp.entities.Ad;
import com.stevan.madsapp.exceptions.ValidationException;
import com.stevan.madsapp.security.components.TokenIdCheck;
import com.stevan.madsapp.services.AdService;
import com.stevan.madsapp.validators.AdValidator;
import com.stevan.madsapp.web.dto.AdDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
#RestController
#RequestMapping(value = "/api/forms", produces = MediaType.APPLICATION_JSON_VALUE)
#CrossOrigin(origins = "http://localhost:4200")
public class AdController {
#Autowired
private AdService adService;
#Autowired
private AdValidator adValidator;
#Autowired
private TokenIdCheck tokenIdCheck;
#GetMapping(value = "/statuscheck")
private ResponseEntity<Object> check()
{
return new ResponseEntity<>(HttpStatus.OK);
}
#GetMapping
private ResponseEntity<List<AdDTO>> getAllAds(#RequestHeader("id") Integer id)
{
List<AdDTO> adList = adService.getAds(id);
return new ResponseEntity<>(adList, HttpStatus.OK);
}
#GetMapping(value = "/request")
private ResponseEntity<AdDTO> getAd(#RequestHeader("adId") Integer adId,
#RequestHeader("Authorization") String token,
#RequestHeader("id") Integer id)
{
if(tokenIdCheck.check(id, token))
{
AdDTO adDTO = adService.requestAd(adId, id);
if(adDTO != null)
{
return new ResponseEntity<>(adDTO, HttpStatus.OK);
}
}
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
#PostMapping
private ResponseEntity<AdDTO> uploadAd(#RequestBody AdDTO adDTO,
#RequestHeader("id") Integer id) throws ValidationException
{
Errors optionalErrors = new BeanPropertyBindingResult(adDTO, "adDTO");
ValidationUtils.invokeValidator(adValidator, adDTO, optionalErrors);
if(optionalErrors.hasErrors())
{
throw new ValidationException(optionalErrors);
}
Ad newAd = adService.store(adDTO, id);
return newAd != null
? new ResponseEntity<>(adService.convertToDTO(newAd), HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
To clarify more thouroughly now, when I sysout an Ads questions, right after I store it, it shows that it has some questions, but when I do it when requesting an Ad later, it shows an empty list. In mysql they have their apropriate foreign keys.
I had to save the ad_id in the Question entity before I added that question to the questions_id list in the Ad entity. The only problem I had with that is that in order to set the parent Ad as the ad_id in every question, I needed to save the Ad itself first.
Here are the changes:
In AdService:
public Ad store(AdDTO ad, Integer id) {
Ad newAd = new Ad();
newAd.setName(ad.getName());
newAd.setAuthor(userDetailsService.getUserDetails(id));
newAd.setJob(jobService.getJob(ad.getJobId()));
newAd.setCountry(countryService.getCountry(ad.getCountryId()));
adRepository.save(newAd);
Set<Question> newQuestions = newAd.getQuestions();
for(Question question : ad.getQuestions())
{
Question newQuestion = questionService.store(question, newAd);
newQuestions.add(newQuestion);
}
adRepository.save(newAd);
System.out.println(adRepository.getById(newAd.getId()).getQuestions());
return newAd;
}
I just added another adRepository.save(newAd) before cycling through questions, and changed the store Question method to take in an Ad, which I used to set the ad_id in questions.
and in QuestionService:
public Question store(Question question, Ad newAd)
{
Question newQuestion = new Question();
newQuestion.setQuestion(question.getQuestion());
newQuestion.setType(question.getType());
newQuestion.setAd(newAd);
if (newQuestion.getType().equals("radio"))
{
List<McOption> newMcOptions = new ArrayList<>();
for (McOption mcOption : question.getRadioOptions())
{
McOption newMcOption = mcOptionService.store(mcOption);
newMcOptions.add(newMcOption);
}
newQuestion.setRadioOptions(newMcOptions);
}
else if(newQuestion.getType().equals("checkbox"))
{
List<McOption> newMcOptions = new ArrayList<McOption>();
for (McOption mcOption : question.getCheckboxOptions())
{
McOption newMcOption = mcOptionService.store(mcOption);
newMcOptions.add(newMcOption);
}
newQuestion.setCheckboxOptions(newMcOptions);
}
questionRepository.save(newQuestion);
return newQuestion;
}
Basically I am not understanding that how to send data rest-api class using Postman ?
When I use Postman to run rest-api to save record it gives me errors like application json format not supported..
I have following class to represent Many to Many relation
package com.ps.usercourse;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.ps.course.Course;
import com.ps.user.User;
#Entity
public class UserCourse implements Serializable
{
private static final long serialVersionUID = 46419863112677606L;
#EmbeddedId
private UserCourseId id;
#ManyToOne
#MapsId("emailId")
#JsonBackReference
User user;
#ManyToOne
#MapsId("courseId")
#JsonBackReference
Course course;
Boolean isActive = true;
public UserCourse() {
}
public UserCourse(User user, Course course, Boolean isActive) {
this.user = user;
this.course = course;
this.isActive = isActive;
}
public UserCourse(UserCourseId id, User user, Course course, Boolean isActive) {
this.id = id;
this.user = user;
this.course = course;
this.isActive = isActive;
}
public UserCourseId getId() {
return id;
}
public void setId(UserCourseId id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public Boolean getIsActive() {
return isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
UserCourse that = (UserCourse) o;
return Objects.equals(user, that.user) &&
Objects.equals(course, that.course);
}
#Override
public int hashCode() {
return Objects.hash(user, course);
}
}
This is rest api that I am trying to call through Postman
#RequestMapping(value="/UserCourse",method=RequestMethod.POST)
#ResponseBody
public UserCourse addUser(#RequestBody UserCourse userCourse, HttpServletRequest req, HttpServletResponse res)
{
return userCourseService.save(userCourse);
}
I am trying to create Spring boot application with JPARepository.My aim is to create the application generic.
In my application i have 4 common functionalities for all the entities as follows :
getAll
getAllNewAfterLastSyncDate
getAllModifiedAfterLastSyncDate
getAllDeletedAfterLastSyncDate
To achive this and avoid redundency of code i created one generic base repository which extends JPARepository as follows :
BaseRepository.java
package dev.ashish.syncdemo.utlities;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.NoRepositoryBean;
#NoRepositoryBean
public interface BaseRepository<T> extends JpaRepository<T, Long>{
**#Query("select t from #{#entityName} t where t.deleteFlag = 'F' ")**
public List<T> getAll();
/*public List<T> getAllNewAfterLastSyncDate();
public List<T> getAllModifiedAfterLastSyncDate();
public List<T> getAllDeletedAfterLastSyncDate();
*/
}
I have created common bean which will be extended by all entities in my aplication as it has 5 common attributes or fields used for all entities.
CommonBean.java
package dev.ashish.syncdemo.beans;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class CommonBean {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="id")
private Long id;
#Column(name = "code")
private String code;
#Column(name = "created_by")
private Long createdBy;
#Column(name = "created_oy")
private Timestamp createdOn;
#Column(name = "modified_by")
private Long modifiedBy;
#Column(name = "modified_on")
private Timestamp modifiedOn;
#Column(name = "delete_flag")
private String deleteFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Long getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Long createdBy) {
this.createdBy = createdBy;
}
public Timestamp getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Timestamp createdOn) {
this.createdOn = createdOn;
}
public Long getModifiedBy() {
return modifiedBy;
}
public void setModifiedBy(Long modifiedBy) {
this.modifiedBy = modifiedBy;
}
public Timestamp getModifiedOn() {
return modifiedOn;
}
public void setModifiedOn(Timestamp modifiedOn) {
this.modifiedOn = modifiedOn;
}
public String getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(String deleteFlag) {
this.deleteFlag = deleteFlag;
}
}
Now Consider i want to use this for customer entity
CustomerEntity.java
package dev.ashish.syncdemo.beans;
import javax.persistence.Column;
public class CustomerEntity extends CommonBean{
#Column(name="first_name")
private String firstName;
#Column(name="middle_name")
private String middleName;
#Column(name="last_name")
private String lastName;
#Column(name="address1")
private String address1;
#Column(name="address2")
private String address2;
#Column(name="landline_no")
private String landlineNo;
#Column(name="mobile_no")
private String mobileNo;
#Column(name="email_id")
private String emailId;
#Column(name="city")
private String city;
#Column(name="state")
private String state;
#Column(name="country")
private String country;
#Column(name="pin_code")
private String pinCode;
#Column(name="fax_number")
private String faxNumber;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getLandlineNo() {
return landlineNo;
}
public void setLandlineNo(String landlineNo) {
this.landlineNo = landlineNo;
}
public String getMobileNo() {
return mobileNo;
}
public void setMobileNo(String mobileNo) {
this.mobileNo = mobileNo;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPinCode() {
return pinCode;
}
public void setPinCode(String pinCode) {
this.pinCode = pinCode;
}
public String getFaxNumber() {
return faxNumber;
}
public void setFaxNumber(String faxNumber) {
this.faxNumber = faxNumber;
}
#Override
public String toString() {
return "CustomerEntity [firstName=" + firstName + ", middleName=" + middleName + ", lastName=" + lastName
+ ", address1=" + address1 + ", address2=" + address2 + ", landlineNo=" + landlineNo + ", mobileNo="
+ mobileNo + ", emailId=" + emailId + ", city=" + city + ", state=" + state + ", country=" + country
+ ", pinCode=" + pinCode + ", faxNumber=" + faxNumber + ", getId()=" + getId() + ", getCode()="
+ getCode() + ", getCreatedBy()=" + getCreatedBy() + ", getCreatedOn()=" + getCreatedOn()
+ ", getModifiedBy()=" + getModifiedBy() + ", getModifiedOn()=" + getModifiedOn() + ", getDeleteFlag()="
+ getDeleteFlag() + "]";
}
}
I created CustomerService which extends BaseRepositoy as follows:
CustomerService.java
package dev.ashish.syncdemo.service;
import org.springframework.stereotype.Service;
import dev.ashish.syncdemo.beans.CustomerEntity;
import dev.ashish.syncdemo.utlities.BaseRepository;
#Service("customerService")
public interface CustomerService extends BaseRepository<CustomerEntity>{
}
FrontController.java
package dev.ashish.syncdemo.controller;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import dev.ashish.syncdemo.service.CustomerService;
import dev.ashish.syncdemo.utlities.Constants;
#RestController
#RequestMapping("/frontgate")
public class FrontController {
#Autowired
private CustomerService customerService;
#RequestMapping(value = "/getres", method = RequestMethod.POST)
public String getRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
String reqStr = request.getReader().readLine();
System.out.println("Request is : " + reqStr);
Map<String, Object> reqMap = new Gson().fromJson(reqStr, new TypeToken<HashMap<String, Object>>() {
}.getType());
System.out.println("Req Map " + reqMap);
return parseRequest(reqMap);
}
public String parseRequest(Map<String, Object> reqMap)
{
String entity = (String)reqMap.get(Constants.ENTITY);
String action = (String)reqMap.get(Constants.ACTION);
String pageSize = (String)reqMap.get(Constants.PAGE_SIZE);
String pageNumber = (String)reqMap.get(Constants.PAGE_NUMBER);
String lastSyncDate = (String)reqMap.get(Constants.LAST_SYNC_DATE);
return customerService.getAll().toString();
}
}
SyncDemoApplication.java
package dev.ashish;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class SyncDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SyncDemoApplication.class, args);
}
}
Application flow is as follows:
Request will come to FrontController then it will be forwarded to customerservice which is extending base repository of type JPArepository.
As there are all common functionalities i dont want to create repository for all entities separately and write query for each of them. As you can see i am using SPEL #{#entityName} passing entity name at runtime to query in #Query annotation.
When i try to run application it gives me following exception :
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'demo-db.common_bean' doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.7.0_67]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[na:1.7.0_67]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[na:1.7.0_67]
at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[na:1.7.0_67]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:389) ~[mysql-connector-java-5.1.35.jar:5.1.35]
Query being fired is as follows :
Hibernate: select customeren0_.id as id2_0_, customeren0_.code as code3_0_, customeren0_.created_by as created_4_0_, customeren0_.created_oy as created_5_0_, customeren0_.delete_flag as delete_f6_0_, customeren0_.modified_by as modified7_0_, customeren0_.modified_on as modified8_0_, customeren0_.address1 as address9_0_, customeren0_.address2 as address10_0_, customeren0_.city as city11_0_, customeren0_.country as country12_0_, customeren0_.email_id as email_i13_0_, customeren0_.fax_number as fax_num14_0_, customeren0_.first_name as first_n15_0_, customeren0_.landline_no as landlin16_0_, customeren0_.last_name as last_na17_0_, customeren0_.middle_name as middle_18_0_, customeren0_.mobile_no as mobile_19_0_, customeren0_.pin_code as pin_cod20_0_, customeren0_.state as state21_0_
from **common_bean** customeren0_ where customeren0_.dtype='CustomerEntity' and customeren0_.delete_flag='F'
Instead of common_bean in from clause it should be customer as i am doing operation for entity customer.
Please let me know what i am doing wrong.
I am working with JPA and I am trying to insert foreign key value its working fine but during modifying it is updating null values..
Please Refer following code
package com.bcits.bfm.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name="JOB_CALENDER")
public class JobCalender implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int jobCalenderId;
private int scheduleType;
private String title;
private String description;
private String recurrenceRule;
private String recurrenceException;
private int recurrenceId;
private boolean isAllDay;
private Date start;
private Date end;
private String jobNumber;
private String jobGroup;
private int expectedDays;
private String jobPriority;
private String jobAssets;
private MaintainanceTypes maintainanceTypes;
private MaintainanceDepartment departmentName;
private JobTypes jobTypes;
#Id
#Column(name="JOB_CALENDER_ID")
#SequenceGenerator(name = "JOB_CALENDER_SEQUENCE", sequenceName = "JOB_CALENDER_SEQUENCE")
#GeneratedValue(generator = "JOB_CALENDER_SEQUENCE")
public int getJobCalenderId() {
return jobCalenderId;
}
public void setJobCalenderId(int jobCalenderId ) {
this.jobCalenderId = jobCalenderId ;
}
#Column(name="SCHEDULE_TYPE")
public int getScheduleType() {
return scheduleType;
}
public void setScheduleType(int scheduleType) {
this.scheduleType = scheduleType;
}
#Column(name="START_DATE")
public Date getStart() {
return start;
}
public void setStart(Date start) {
this.start = start;
}
#Column(name="END_DATE")
public Date getEnd() {
return end;
}
public void setEnd(Date end) {
this.end = end;
}
#Column(name="Title")
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
#Column(name="DESCRIPTION")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name="RECURRENCE_RULE")
public String getRecurrenceRule() {
return recurrenceRule;
}
public void setRecurrenceRule(String recurrenceRule) {
this.recurrenceRule = recurrenceRule;
}
#Column(name="IS_ALL_DAY")
public boolean getIsAllDay() {
return isAllDay;
}
public void setIsAllDay(boolean isAllDay) {
this.isAllDay = isAllDay;
}
#Column(name="RECURENCE_EXCEPTION")
public String getRecurrenceException() {
return recurrenceException;
}
public void setRecurrenceException(String recurrenceException) {
this.recurrenceException = recurrenceException;
}
#Column(name="RECURRENCE_ID")
public int getRecurrenceId() {
return recurrenceId;
}
public void setRecurrenceId(int recurrenceId) {
this.recurrenceId = recurrenceId;
}
/*Custom Columns*/
#Column(name = "JOB_NUMBER", nullable = false, length = 45)
public String getJobNumber() {
return this.jobNumber;
}
public void setJobNumber(String jobNumber) {
this.jobNumber = jobNumber;
}
#Column(name = "JOB_GROUP", nullable = false, length = 45)
public String getJobGroup() {
return this.jobGroup;
}
public void setJobGroup(String jobGroup) {
this.jobGroup = jobGroup;
}
#Column(name = "EXPECTED_DAYS", nullable = false, precision = 11, scale = 0)
public int getExpectedDays() {
return this.expectedDays;
}
public void setExpectedDays(int expectedDays) {
this.expectedDays = expectedDays;
}
#Column(name = "JOB_PRIORITY", nullable = false, length = 45)
public String getJobPriority() {
return this.jobPriority;
}
public void setJobPriority(String jobPriority) {
this.jobPriority = jobPriority;
}
#Column(name = "JOB_ASSETS", nullable = false, length = 4000)
public String getJobAssets() {
return this.jobAssets;
}
public void setJobAssets(String jobAssets) {
this.jobAssets = jobAssets;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "JOB_DEPT_ID",referencedColumnName="MT_DP_IT",nullable = false)
public MaintainanceDepartment getMaintainanceDepartment() {
return this.departmentName;
}
public void setMaintainanceDepartment(
MaintainanceDepartment departmentName) {
this.departmentName = departmentName;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "JOB_TYPE_ID",referencedColumnName="JT_ID",nullable = false)
public JobTypes getJobTypes() {
return this.jobTypes;
}
public void setJobTypes(JobTypes jobTypes) {
this.jobTypes = jobTypes;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "MAINTAINANCE_TYPE_ID",nullable = false)
public MaintainanceTypes getMaintainanceTypes() {
return this.maintainanceTypes;
}
public void setMaintainanceTypes(MaintainanceTypes maintainanceTypes) {
this.maintainanceTypes = maintainanceTypes;
}
}
And Parent Table Is
package com.bcits.bfm.model;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
/**
* MaintainanceTypes entity. #author MyEclipse Persistence Tools
*/
#Entity
#Table(name = "MAINTAINANCE_TYPES")
public class MaintainanceTypes implements java.io.Serializable {
private static final long serialVersionUID = 1L;
// Fields
private int mtId;
private String maintainanceType;
private String description;
private Timestamp mtDt;
private String createdBy;
private String lastUpdatedBy;
private Timestamp lastUpdatedDt;
private Set<JobCards> jobCardses = new HashSet<JobCards>(0);
private Set<JobCalender> jobCalenders = new HashSet<JobCalender>(0);
// Constructors
/** default constructor */
public MaintainanceTypes() {
}
/** minimal constructor */
public MaintainanceTypes(int mtId, String maintainanceType, Timestamp mtDt) {
this.mtId = mtId;
this.maintainanceType = maintainanceType;
this.mtDt = mtDt;
}
/** full constructor */
public MaintainanceTypes(int mtId, String maintainanceType,
String description, Timestamp mtDt, String createdBy,
String lastUpdatedBy, Timestamp lastUpdatedDt,
Set<JobCards> jobCardses) {
this.mtId = mtId;
this.maintainanceType = maintainanceType;
this.description = description;
this.mtDt = mtDt;
this.createdBy = createdBy;
this.lastUpdatedBy = lastUpdatedBy;
this.lastUpdatedDt = lastUpdatedDt;
this.jobCardses = jobCardses;
}
// Property accessors
#Id
#Column(name = "MT_ID", unique = true, nullable = false, precision = 11, scale = 0)
#SequenceGenerator(name = "MAINTENANCE_TYPES_SEQ", sequenceName = "MAINTENANCE_TYPES_SEQ")
#GeneratedValue(generator = "MAINTENANCE_TYPES_SEQ")
public int getMtId() {
return this.mtId;
}
public void setMtId(int mtId) {
this.mtId = mtId;
}
#Column(name = "MAINTAINANCE_TYPE", nullable = false, length = 20)
public String getMaintainanceType() {
return this.maintainanceType;
}
public void setMaintainanceType(String maintainanceType) {
this.maintainanceType = maintainanceType;
}
#Column(name = "DESCRIPTION", length = 200)
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "MT_DT", nullable = false, length = 11)
public Timestamp getMtDt() {
return this.mtDt;
}
public void setMtDt(Timestamp mtDt) {
this.mtDt = mtDt;
}
#Column(name = "CREATED_BY", length = 45)
public String getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
#Column(name = "LAST_UPDATED_BY", length = 45)
public String getLastUpdatedBy() {
return this.lastUpdatedBy;
}
public void setLastUpdatedBy(String lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
#Column(name = "LAST_UPDATED_DT", length = 11)
public Timestamp getLastUpdatedDt() {
return this.lastUpdatedDt;
}
public void setLastUpdatedDt(Timestamp lastUpdatedDt) {
this.lastUpdatedDt = lastUpdatedDt;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "maintainanceTypes")
public Set<JobCards> getJobCardses() {
return this.jobCardses;
}
public void setJobCardses(Set<JobCards> jobCardses) {
this.jobCardses = jobCardses;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "maintainanceTypes")
public Set<JobCalender> getJobCalenders() {
return this.jobCalenders;
}
public void setJobCalenders(Set<JobCalender> jobCalenders) {
this.jobCalenders = jobCalenders;
}
}
I am calling below method to Update
public void Update(JobCalender jobCalender) {
update(jobCalender); //update() is generic method
}
public T update(final T t) {
BfmLogger.logger.info("updating "+t+" instance");
try {
T result = this.entityManager.merge(t);
BfmLogger.logger.info("update successful");
return result;
} catch (RuntimeException re) {
BfmLogger.logger.error("update failed", re);
throw re;
}
}
My Controller Code
#RequestMapping(value = "/index/create", method = RequestMethod.POST)
public #ResponseBody List<?> create(#RequestBody Map<String, Object>model,#ModelAttribute JobCalender jobCalender,BindingResult bindingResult, HttpServletRequest request) throws ParseException {
jobCalender.setDescription((String)model.get("description"));
jobCalender.setTitle((String)model.get("title"));
SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-M-dd'T'HH:mm:ss.SSS'Z'");
iso8601.setTimeZone(TimeZone.getTimeZone("UTC"));
jobCalender.setStart(iso8601.parse((String)model.get("start")));
jobCalender.setEnd(iso8601.parse((String)model.get("end")));
jobCalender.setIsAllDay((boolean) model.get("isAllDay"));
jobCalender.setRecurrenceRule((String)model.get("recurrenceRule"));
jobCalender.setRecurrenceException((String)model.get("recurrenceException"));
if(model.get("recurrenceId")!=null)
jobCalender.setRecurrenceId((Integer)model.get("recurrenceId"));
jobCalender.setScheduleType(Integer.parseInt(model.get("scheduleType").toString()));
jobCalender.setJobNumber((String) model.get("jobNumber"));
jobCalender.setDescription((String) model.get("description"));
jobCalender.setJobGroup((String) model.get("jobGroup"));
jobCalender.setMaintainanceDepartment(maintainanceDepartmentService.find(Integer.parseInt(model.get("departmentName").toString())));
jobCalender.setMaintainanceTypes(maintainanceTypesService.find(Integer.parseInt(model.get("maintainanceTypes").toString())));
jobCalender.setJobTypes(jobTypesService.find(Integer.parseInt(model.get("jobTypes").toString())));
jobCalender.setJobPriority((String) model.get("jobPriority"));
String ids="";
#SuppressWarnings("unchecked")
List<Map<String, Object>> listAssets = (ArrayList<Map<String, Object>>) model.get("assetName");// this is what you have already
for (Map<String, Object> map1 :listAssets) {
for (Map.Entry<String, Object> entry : map1.entrySet()) {
if(entry.getKey().equalsIgnoreCase("assetId")){
ids+=entry.getValue()+",";
}
}
}
jobCalender.setJobAssets(ids);
jobCalenderService.Update(jobCalender);
}
while Updating JOB_CALENDER Table it is Adding NULL Value For MAINTAINANCE_TYPE_ID Column
Please Help Me
Thank You
Regards
Manjunath Kotagi