Spring Boot Jpa #ManyToOne : ForeignKey column in DB always populated to null - spring

Employee.Java
`
import lombok.ToString;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
#ToString
#Entity
public class Employee {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int empid;
private String empname;
private String empcontact;
private String empemail;
private String empphoto;
#OneToMany(mappedBy = "employee", cascade = CascadeType.ALL)
private List<Skillset> skillset;
public int getEmpid() {
return empid;
}
public void setEmpid(int empid) {
this.empid = empid;
}
public String getEmpname() {
return empname;
}
public void setEmpname(String empname) {
this.empname = empname;
}
public String getEmpcontact() {
return empcontact;
}
public void setEmpcontact(String empcontact) {
this.empcontact = empcontact;
}
public String getEmpemail() {
return empemail;
}
public void setEmpemail(String empemail) {
this.empemail = empemail;
}
public String getEmpphoto() {
return empphoto;
}
public void setEmpphoto(String empphoto) {
this.empphoto = empphoto;
}
public List<Skillset> getSkillset() {
return skillset;
}
public void setSkillset(List<Skillset> skillset) {
this.skillset = skillset;
}`
SkillSet.Java
`
package aurozen.assign.aurozenassign.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.ToString;
import javax.persistence.*;
#Entity
public class Skillset {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int skillid;
private String skillname;
#JsonIgnore
#ManyToOne
#JoinColumn(name = "empId", nullable = false,updatable = false, insertable = true)
private Employee employee;
public int getSkillid() {
return skillid;
}
public void setSkillid(int skillid) {
this.skillid = skillid;
}
public String getSkillname() {
return skillname;
}
public void setSkillname(String skillname) {
this.skillname = skillname;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
#Override
public String toString() {
return "Skillset{" +
"skillid='" + skillid + '\'' +
", skillname='" + skillname + '\'' +
", employee=" + employee +
'}';
}
}
`
EmployeeRepositry.java
package aurozen.assign.aurozenassign.repositry;
import aurozen.assign.aurozenassign.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
#Repository
public interface EmployeeRepositry extends JpaRepository<Employee, Integer> {
Optional<Employee> findByEmpcontact(String s);
}
SkillSetRepositry.java
package aurozen.assign.aurozenassign.repositry;
import aurozen.assign.aurozenassign.entity.Skillset;
import org.springframework.data.jpa.repository.JpaRepository;
public interface SkillsetRepositry extends JpaRepository<Skillset, Integer> {
}
Controller
#PostMapping(value = "/signup",produces = {"application/json"})
public Employee addEmployee(#RequestBody Employee employee) {
empRepo.save(employee);
return employee;
}
Json Data
{
"empname": "sandep",
"empcontact": "9650114890",
"empemail": "aidaih",
"empphoto": "paidpaid",
"skillset": [
{
"skillname": "jop"
}
]
}
I have attached Db Screenshot
Database Screenshot with empid as foreign key in skillset table
foreign key(empid) in the skillset table always populating to null when ever I try to post the data through postman.other fields getting populating without any problem in both the table

The relationship between Skillset and Employee is owned by Skillset. This means JPA will persist the state the Skillset objects have.
But via #RequestBody you are creating an Employee instance.
While that references a Skillset instances, that instance does not reference the Employee.
Therefor no relationship gets persisted.
To fix this add code to setSkillset to set the employee property of it.
Something like this should do:
public void setSkillset(List<Skillset> skillset) {
this.skillset = skillset;
skillset.foreach(s -> s.setEmployee(this));
}

Related

Why am I getting null for the date when I create a Todo entity?

What is wrong with my to-do application? I want the user to be able to add a todo and have it be saved in my MySQL database with the time it was created, but I don't know what I'm doing wrong.
I am new to learning Springboot and would appreciate any suggestions or advice.
Todo Entity:
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import java.util.Date;
#Entity(name = "Todo")
#NoArgsConstructor
#Table(name = "todos")
public class Todo {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name="description")
private String description;
#Column(name="target_date")
#CreationTimestamp
private Date targetDate;
public Todo(String description) {
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getTargetDate() {
return targetDate;
}
public void setTargetDate(Date targetDate) {
this.targetDate = targetDate;
}
#Override
public String toString() {
return "Todo{" +
"id=" + id +
", description='" + description + '\'' +
", targetDate=" + targetDate +
'}';
}
}
Adding a Todo with Spring Data JPA
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.List;
#Repository
#Component
public interface TodoRepository extends JpaRepository<Todo, Integer> {
#Modifying
#Query(value = "INSERT INTO todos (description) VALUES (:description)", nativeQuery=true)
#Transactional
void addTodo(#Param("description") String description);
}
TodoController
#RestController
#RequestMapping(value = "/api/v1/todos")
#AllArgsConstructor
public class TodoController {
#Autowired
private ITodoService todoService;
#PostMapping(value = "/add-todo")
public String addTodo(#RequestParam String description) {
Todo todo = new Todo();
todo.setDescription(description);
todoService.addTodo(todo);
return todo.toString();
}
after getting a post request, the target_date is getting NULL in MySQL
I assume you can solve it by using persist():
#Autowired EntityManager entityManager;
#PostMapping(value = "/add-todo")
public String addTodo(#RequestParam String description) {
Todo todo = new Todo();
todo.setDescription(description);
entityManager.persist(todo);
return todo.toString();
}

JPA #OneToMany mapping inserting null values

I had a hard time with hibernate OneToMany mapping. I have googled to find the solution from morning nothing helped. Following are my code snippets.
package com.student.app.model;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonProperty;
#Entity
#Table(name = "student")
public class Student {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "student_id")
private long id;
#Column(name = "student_name")
private String name;
#Column(name = "student_class")
#JsonProperty("class")
private String clazz;
#Column(name = "total_marks")
private int totalMarks;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "student")
private List<Subject> subjects;
public Student() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public int getTotalMarks() {
return totalMarks;
}
public void setTotalMarks(int totalMarks) {
this.totalMarks = totalMarks;
}
public List<Subject> getSubjects() {
return subjects;
}
public void setSubjects(List<Subject> subjects) {
this.subjects = subjects;
}
#Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", clazz=" + clazz + ", totalMarks=" + totalMarks
+ ", subjects=" + subjects + "]";
}
}
Subject.java
package com.student.app.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name = "subject")
public class Subject {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "subject_id")
private long id;
#Column(name = "subject_name")
private String name;
#Column(name = "marks")
private String marks;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "student_id")
private Student student;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMarks() {
return marks;
}
public void setMarks(String marks) {
this.marks = marks;
}
#Override
public String toString() {
return "Subject [id=" + id + ", name=" + name + ", marks=" + marks + "]";
}
}
StudentRepository.java
package com.student.app.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.student.app.model.Student;
#Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
Student findStudentByName(String name);
}
POST Mapping
#PostMapping("/students")
public ResponseEntity<?> addStudent(#RequestBody Student student) {
try {
System.out.println("Student Object is : " + student);
Student studentData = studentRepository.save(student);
if (null == studentData) {
return ResponseEntity.noContent().build();
}
URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{name}")
.buildAndExpand(studentData.getName()).toUri();
return new ResponseEntity<>(location, HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Post Request JSON
{
"name": "Vinod Kumar",
"class": "8th class",
"subjects": [
{
"name": "Telugu",
"marks": 85
},
{
"name": "English",
"marks": 80
},
{
"name": "Maths",
"marks": 90
}
],
"totalMarks": 580
}
Student Table data
STUDENT_ID STUDENT_CLASS STUDENT_NAME TOTAL_MARKS
1 8th class Vinod Kumar 580
Subject Table data
SUBJECT_ID MARKS SUBJECT_NAME STUDENT_ID
2 85 Telugu null
3 80 English null
4 90 Maths null
Here the issue is the STUDENT_ID column storing null values.
When you save a Student, Hibernate smart enough to insert a Student record to the database, get that record id and save all subjects of the Student with Subject.STUDENT_ID = generated student id, when the student and the subject connected to each other from both sides.
But by some reasons Hibernate doesn't connect a Subject with a Student as Java objects from the Subject side. It doesn't do for you
subject.setStudent(student)
This is the reason why Subject.STUDENT_ID = null in the database.
Before saving a student you have to assign the student to a subject for each subject, doing it in the loop
emptyStreamIfNull(student.getSubjects()).forEach(subject -> setStudent(student));
Some recommendations
Your database schema is not convenient. Student and Subject are tabular data.
So you need an additional object StudentSubjectMark.
Also use Long id for ids (not long id).
You have to log error here
catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}

Get from VIEW in Spring boot

I am beginner with Spring Boot and trying to improve my skills to get new job, so I hope you help me even if the question maybe easy for you as I search a lot and gain nothing.
I need to get by id, but return data is duplicated with only one record, I will show you what I do and the result for more explanation.
In DB side:
I have VW_Prices view in DB and it's data as shown below:
In Spring Boot side:
VW_Prices class is :
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Immutable;
#Entity
#Table(name = "VW_PRICES")
public class VW_Prices implements Serializable {
private long dealId;
private Long quotationId;
private Long productPriceForEjada;
private Long productPriceForClient;
private Long productId;
private Long productQuantity;
private String productName;
#Id
#Column(name = "ID")
public long getDealId() {
return dealId;
}
public void setDealId(long dealId) {
this.dealId = dealId;
}
#Column(name = "PRODUCT_QUANTITY")
public Long getProductQuantity() {
return productQuantity;
}
public void setProductQuantity(Long productQuantity) {
this.productQuantity = productQuantity;
}
#Column(name = "PRODUCT_NAME")
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
#Column(name = "PRODUCT_PRICE_FOR_EJADA")
public Long getProductPriceForEjada() {
return productPriceForEjada;
}
public void setProductPriceForEjada(Long productPriceForEjada) {
this.productPriceForEjada = productPriceForEjada;
}
#Column(name = "PRODUCT_PRICE_FOR_CLIENT")
public Long getProductPriceForClient() {
return productPriceForClient;
}
public void setProductPriceForClient(Long productPriceForClient) {
this.productPriceForClient = productPriceForClient;
}
#Column(name = "PRODUCT_ID")
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
#Column(name = "QUOTATION_ID")
public Long getQuotationId() {
return quotationId;
}
public void setQuotationId(Long quotationId) {
this.quotationId = quotationId;
}
}
and I create VW_PricesRepository
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import springboot.deals_tracker_system.models.VW_Prices;
import springboot.deals_tracker_system.models.VW_Prices_interface;
public interface VW_PricesRepository extends JpaRepository<VW_Prices, Long> {
#Query( nativeQuery = true,value = "SELECT distinct * from VW_Prices v where v.id = :dealID " )
List<VW_Prices> findByDealId( #Param("dealID") Long id);
}
and my in my Service
public List<VW_Prices> findByDealId(Long dealId) {
System.out.println("we are in service");
List<VW_Prices> variableForDebug = VW_pricesRepository.findByDealId(dealId);
for (VW_Prices vw_Prices : variableForDebug) {
System.out.println(vw_Prices.getDealId() + " " + vw_Prices.getProductName());
}
return variableForDebug;
//return VW_pricesRepository.findByDealId(dealId);
}
When I pass dealId = 39 the result comes duplicated and not correct as in below:
how can I get correct data??
The view is made for Quotation Product Table to get product name.
i think the problem is the id annotation you must add GeneratedValue
fro the class:
#Entity
#Table(name = "VW_PRICES")
public class VW_Prices implements Serializable {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
private long dealId;
private Long quotationId;
private Long productPriceForEjada;
private Long productPriceForClient;
private Long productId;
private Long productQuantity;
private String productName;
//code..
}
You dont have to use JPQL for this type of queries it's already exist in jpa:
VW_PricesRepository:
public interface VW_PricesRepository extends JpaRepository<VW_Prices, Long> {
}
to get data by id use findById like that:
public VW_Prices findByDealId(Long dealId) {
System.out.println("we are in service");
VW_Prices vw_Prices = VW_pricesRepository.findById(dealId);
System.out.println(vw_Prices.getDealId() + " " +
vw_Prices.getProductName());
}
return vw_Prices;
}
All data should be deleted from VW_Prices table because ids are not unique, try to insert new data with unique id then try the above code
I detect the problem, The view has main table Quotation and I didn't select it's ID and I used ID of the secondary table as the main ID for the View
I just write it if any one Google for such problem

Calling a one to many list in a saved entity returns null

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;
}

SpringBoot+Neo4J OGM update record

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);
}
}

Resources