I have been scratching my head for more than an hour and being unable to find solutions. i have two entities classes. one of them being Questions.java and other being Answers.java
Question.java
#Entity
#Table
public class Questions {
#Id
#Column(name = "ques_id")
private int ques_id;
#Column(name = "question")
private String question;
#Column(name = "type")
private String type;
#Column(name = "description")
private String description;
#Column(name = "param")
private String param;
#Column(name = "maxlength")
private int maxlength;
#Column(name = "dependency")
private String dependency;
#OneToMany(mappedBy = "questions",targetEntity = Answers.class, cascade = CascadeType.ALL)
private List<Answers> answers = new ArrayList<>();
public int getQues_id() {
return ques_id;
}
public void setQues_id(int ques_id) {
this.ques_id = ques_id;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public int getMaxlength() {
return maxlength;
}
public void setMaxlength(int maxlength) {
this.maxlength = maxlength;
}
public String getDependency() {
return dependency;
}
public List<Answers> getAnswers() {
return answers;
}
public void setAnswers(List<Answers> answers) {
this.answers = answers;
}
public void setDependency(String dependency) {
this.dependency = dependency;
}
}
Answers.java
#Entity
public class Answers {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "ans_label")
private String ans_label;
#Column(name = "ans_value")
private int ans_value;
#Column(name = "ans_weightage")
private int ans_weightage;
#Column(name = "is_default")
private int is_default;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "ques_id")
private Questions questions;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAns_label() {
return ans_label;
}
public void setAns_label(String ans_label) {
this.ans_label = ans_label;
}
public int getAns_value() {
return ans_value;
}
public void setAns_value(int ans_value) {
this.ans_value = ans_value;
}
public int getAns_weightage() {
return ans_weightage;
}
public void setAns_weightage(int ans_weightage) {
this.ans_weightage = ans_weightage;
}
public int getIs_default() {
return is_default;
}
public void setIs_default(int is_default) {
this.is_default = is_default;
}
public Questions getQuestions() {
return questions;
}
public void setQuestions(Questions questions) {
this.questions = questions;
}
}
SaveApiController.java
#RequestMapping(value = "/saveData", method = RequestMethod.POST)
public void saveData(#RequestBody Questions questionss){
//questions.setAnswers(questionss.getAnswers());
saveQuestions.save(questionss);
}
The json data i am sending from postman looks like this.
{
"id": "31",
"question": "३. लिङ्ग ?",
"type": "input_spinner",
"description": null,
"param": "",
"maxlength": "0",
"dependency": null,
"answers": [
{
"ans_label": "पुरुष",
"ans_value": "1",
"ans_weightage": "0",
"is_default": "0"
},
{
"ans_label": "महिला",
"ans_value": "2",
"ans_weightage": "0",
"is_default": "0"
},
{
"ans_label": "अन्य",
"ans_value": "3",
"ans_weightage": "0",
"is_default": "0"
}
]
}
Questions and answers data are all being stored apart from foreign key column in answers table. the column "ques_id" is being stored as NULL.
One of the things that you have to keep in mind is that in order for the persistence provider to Cascade the save operation, you have to set the dependencies on both sides of the relationship..
So Quesions need to have a list of Answers and each of those answers need to have reference to the Questions entity. Only then the cascade will happen.
Not sure if this is the answer to your problem but give it a try.
Related
I've created ManyToMany tables with extra column that's named reqserviceguest_details, then I've tested with filling on my jsp page form to insert the data. When the all data inserted, everything is fine except my servicelaundry_id. It's null and I have no idea why it happened.
ReqServiceGuestDetails.class
#Entity
#Table(name = "reqserviceguest_details")
public class ReqServiceGuestDetails {
#Id
#Column(name = "reqserviceguest_details_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
public int id;
#ManyToOne
#JoinColumn(name = "reqserviceguest_id")
private ReqServiceGuest reqServiceGuest;
#ManyToOne
#JoinColumn(name = "servicelaundry_id")
private ServiceLaundry serviceLaundry;
private int amount;
public ReqServiceGuestDetails() {
}
public ReqServiceGuestDetails(ReqServiceGuest reqServiceGuest, ServiceLaundry serviceLaundry, int amount) {
this.reqServiceGuest = reqServiceGuest;
this.serviceLaundry = serviceLaundry;
this.amount = amount;
}
public ReqServiceGuest getReqServiceGuest() {
return reqServiceGuest;
}
public void setReqServiceGuest(ReqServiceGuest reqServiceGuest) {
this.reqServiceGuest = reqServiceGuest;
}
public ServiceLaundry getServiceLaundry() {
return serviceLaundry;
}
public void setServiceLaundry(ServiceLaundry serviceLaundry) {
this.serviceLaundry = serviceLaundry;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
ReqServiceGuest.class
#Entity
#Table(name = "reqserviceguest")
public class ReqServiceGuest {
#Id
#Column(name = "reqserviceguest_id", nullable = false)
#GeneratedValue(strategy = GenerationType.IDENTITY)
#GenericGenerator(name = "increment", strategy = "increment")
int id;
#Column(nullable = false, unique = true)
private String reqServiceGuestId;
private Date reqDate;
private Date pickDate;
private String type;
private String serviceStatus;
private String guestName;
private String guestTelNo;
#OneToMany(mappedBy = "reqServiceGuest", cascade = CascadeType.ALL)
private Set<ReqServiceGuestDetails> reqServiceGuestDetails = new HashSet<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getReqServiceGuestId() {
return reqServiceGuestId;
}
public void setReqServiceGuestId(String reqServiceGuestId) {
this.reqServiceGuestId = reqServiceGuestId;
}
public Date getReqDate() {
return reqDate;
}
public void setReqDate(Date reqDate) {
this.reqDate = reqDate;
}
public Date getPickDate() {
return pickDate;
}
public void setPickDate(Date pickDate) {
this.pickDate = pickDate;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getServiceStatus() {
return serviceStatus;
}
public void setServiceStatus(String serviceStatus) {
this.serviceStatus = serviceStatus;
}
public String getGuestName() {
return guestName;
}
public void setGuestName(String guestName) {
this.guestName = guestName;
}
public String getGuestTelNo() {
return guestTelNo;
}
public void setGuestTelNo(String guestTelNo) {
this.guestTelNo = guestTelNo;
}
public Set<ReqServiceGuestDetails> getReqServiceGuestDetails() {
return reqServiceGuestDetails;
}
public void setReqServiceGuestDetails(Set<ReqServiceGuestDetails> reqServiceGuestDetails) {
this.reqServiceGuestDetails = reqServiceGuestDetails;
}
}
ServiceLaundry.class
#Entity
#Table(name = "servicelaundry")
public class ServiceLaundry {
#Id
#Column(name = "servicelaundry_id", nullable = false)
#GeneratedValue(strategy = GenerationType.IDENTITY)
#GenericGenerator(name = "increment", strategy = "increment")
int id;
#Column(nullable = false, unique = true)
private String serviceId;
private String serviceName;
private int price;
#OneToMany(mappedBy = "serviceLaundry")
private Set<ReqServiceGuestDetails> reqServiceGuestDetails = new HashSet<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getServiceId() {
return serviceId;
}
public void setServiceId(String serviceId) {
this.serviceId = serviceId;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
And this is form processor in a controller
#RequestMapping(path = "/savereqserviceguest", method = RequestMethod.GET)
public String processAddReqServiceGuestForm (ReqServiceGuest reqServiceGuest, #RequestParam Map<String, String> allParams) {
int latestId = reqServiceGuestService.getLatestReqServiceGuestId();
reqServiceGuest.setReqServiceGuestId(generateReqServiceGuestId(latestId));
reqServiceGuest.setServiceStatus("NP");
/*
for (Map.Entry<String, String> entry : allParams.entrySet()) {
if (entry.getKey().contains("service")) {
String getServiceId = String.valueOf(entry.getKey().charAt(7));
reqServiceGuest.getReqServiceGuestServiceLaundry().add();
}
}
reqServiceGuest.setReqServiceGuestServiceLaundry(serviceGuestDetails);
*/
ServiceLaundry service1 = serviceLaundryService.getServiceLaundry(1);
ServiceLaundry service2 = serviceLaundryService.getServiceLaundry(2);
ReqServiceGuestDetails reqServiceGuestDetails1 = new ReqServiceGuestDetails(reqServiceGuest, service1, 55);
ReqServiceGuestDetails reqServiceGuestDetails2 = new ReqServiceGuestDetails(reqServiceGuest, service2, 35);
reqServiceGuest.getReqServiceGuestDetails().add(reqServiceGuestDetails1);
reqServiceGuest.getReqServiceGuestDetails().add(reqServiceGuestDetails2);
Calendar cReqDate = Calendar.getInstance();
if (reqServiceGuest.getType().equals("Ordinary")) {
Date reqDate = cReqDate.getTime();
reqServiceGuest.setReqDate(reqDate);
Calendar cPickDate = Calendar.getInstance();
cPickDate.add(Calendar.DATE, 5);
Date pickDate = cPickDate.getTime();
reqServiceGuest.setPickDate(pickDate);
} else {
Date reqDate = cReqDate.getTime();
reqServiceGuest.setReqDate(reqDate);
Calendar cPickDate = Calendar.getInstance();
cPickDate.add(Calendar.DATE, 2);
Date pickDate = cPickDate.getTime();
reqServiceGuest.setPickDate(pickDate);
}
reqServiceGuestService.saveReqServiceGuest(reqServiceGuest);
return "redirect:/home";
}
And the final result is
Result
I am new to the JPA world. Here I have tried to make a simple POS. The problem is that when there is no predefined value in tables although the PK is auto-incremented, data is not being inserted into DB. But if I set a predefined row into the tables then there are no issues and data is being inserted successfully. please help me.
The following are my Java classes, and I am using Mysql for DB.
#Entity
#Table(name = "card_payment")
public class Card_payment {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
int id;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "order_id")
private Orders order;
#Column(name = "issuing_bank")
String issuing_bank;
#Column(name = "card_type")
String card_type;
#Column(name = "card_expiry_date")
String card_expiry_date;
#Column(name = "amount")
int amount;
public Card_payment() {
super();
}
public Orders getOrder() {
return order;
}
public void setOrder(Orders order) {
this.order = order;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getIssuing_bank() {
return issuing_bank;
}
public void setIssuing_bank(String issuing_bank) {
this.issuing_bank = issuing_bank;
}
public String getCard_type() {
return card_type;
}
public void setCard_type(String card_type) {
this.card_type = card_type;
}
public String getCard_expiry_date() {
return card_expiry_date;
}
public void setCard_expiry_date(String card_expiry_date) {
this.card_expiry_date = card_expiry_date;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
#Entity
#Table(name = "customer")
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
int id;
#Column(name = "name")
String name;
#Column(name = "mobile_no")
long mobile_no;
#Column(name = "address")
String address;
#OneToMany(mappedBy = "customer", cascade = CascadeType.ALL,
fetch=FetchType.LAZY)
private List<Orders> orders;;
public Customer() {
super();
}
public List<Orders> getOrders() {
return orders;
}
public void setOrders(List<Orders> orders) {
this.orders = orders;
}
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 getMobile_no() {
return mobile_no;
}
public void setMobile_no(long mobile_no) {
this.mobile_no = mobile_no;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
#Entity
#Table(name = "Item")
public class Item {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
int id;
#Column(name = "name")
String name;
#Column(name = "unit")
String unit;
#Column(name = "stock_quantity")
int stock_quantity;
#Column(name = "reorder_level")
int reorder_level;
#Column(name = "unit_price")
int unit_price;
#Column(name = "tax_percentage")
float tax_percentage;
#OneToMany(mappedBy = "item", cascade = CascadeType.ALL,
fetch=FetchType.LAZY)
private List<Orderline> orderLines;
public Item() {
super();
}
public List<Orderline> getOrderLines() {
return orderLines;
}
public void setOrderLines(List<Orderline> orderLines) {
this.orderLines = orderLines;
}
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 String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public int getStock_quantity() {
return stock_quantity;
}
public void setStock_quantity(int stock_quantity) {
this.stock_quantity = stock_quantity;
}
public int getReorder_level() {
return reorder_level;
}
public void setReorder_level(int reorder_level) {
this.reorder_level = reorder_level;
}
public int getUnit_price() {
return unit_price;
}
public void setUnit_price(int unit_price) {
this.unit_price = unit_price;
}
public float getTax_percentage() {
return tax_percentage;
}
public void setTax_percentage(float tax_percentage) {
this.tax_percentage = tax_percentage;
}
}
#Entity
#Table(name = "OrderLine")
public class Orderline {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
int id;
#ManyToOne
#JoinColumn(name = "itemId")
private Item item;
#ManyToOne
#JoinColumn(name = "orderId")
private Orders orders;
#Column(name = "unit_cost")
float unit_cost;
#Column(name = "unit")
int unit;
#Column(name = "tax_percentage")
float tax_percentage;
#Column(name = "quantity")
int quantity;
#Column(name = "amount")
int amount;
#Column(name = "tax_amount")
float tax_amount;
#Column(name = "line_total")
int line_total;
public Orderline() {
super();
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
public Orders getOrders() {
return orders;
}
public void setOrders(Orders orders) {
this.orders = orders;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public float getUnit_cost() {
return unit_cost;
}
public void setUnit_cost(float unit_cost) {
this.unit_cost = unit_cost;
}
public int getUnit() {
return unit;
}
public void setUnit(int unit) {
this.unit = unit;
}
public float getTax_percentage() {
return tax_percentage;
}
public void setTax_percentage(float tax_percentage) {
this.tax_percentage = tax_percentage;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public float getTax_amount() {
return tax_amount;
}
public void setTax_amount(float tax_amount) {
this.tax_amount = tax_amount;
}
public int getLine_total() {
return line_total;
}
public void setLine_total(int line_total) {
this.line_total = line_total;
}
#Entity
#Table(name = "orders")
public class Orders {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
int id;
#ManyToOne
#JoinColumn(name = "customerId")
private Customer customer;
#Column(name = "order_date")
String order_date;
#Column(name = "delivery_address")
String delivery_address;
#Column(name = "total")
long total;
#OneToMany(mappedBy = "orders", cascade = CascadeType.ALL,
fetch=FetchType.LAZY)
private List<Orderline> orderlines;
#OneToOne(mappedBy = "order")
private Cash_payment cash_payment;
#OneToOne(mappedBy = "order")
private Card_payment card_payment;
#OneToOne(mappedBy = "order")
private Cheque_payment cheque_payment;
public Orders() {
super();
}
public Cash_payment getCash_payment() {
return cash_payment;
}
public void setCash_payment(Cash_payment cash_payment) {
this.cash_payment = cash_payment;
}
public Card_payment getCard_payment() {
return card_payment;
}
public void setCard_payment(Card_payment card_payment) {
this.card_payment = card_payment;
}
public Cheque_payment getCheque_payment() {
return cheque_payment;
}
public void setCheque_payment(Cheque_payment cheque_payment) {
this.cheque_payment = cheque_payment;
}
public List<Orderline> getOrderlines() {
return orderlines;
}
public void setOrderlines(List<Orderline> orderlines) {
this.orderlines = orderlines;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getOrder_date() {
return order_date;
}
public void setOrder_date(String order_date) {
this.order_date = order_date;
}
public String getDelivery_address() {
return delivery_address;
}
public void setDelivery_address(String delivery_address) {
this.delivery_address = delivery_address;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
}
public class JPAExample {
private static EntityManager entityManager = EntityManagerUtil.getEntityManager();
public static void main(String[] args) {
JPAExample example = new JPAExample();
entityManager.getTransaction().begin();
Orders order = new Orders();
order.setOrder_date("2019/05/05");
order.setTotal(1000);
order.setDelivery_address("kolkata");
Item item = new Item();
item.setName("cream");
item.setReorder_level(10);
item.setUnit_price(10);
item.setUnit("kg");
item.setTax_percentage((float) 12.5);
item.setStock_quantity(20);
item.setReorder_level(5);
Orderline orderline = new Orderline();
orderline.setAmount(1);
orderline.setItem(item);
orderline.setLine_total(200);
orderline.setQuantity(1);
List<Orderline> orderlns = new ArrayList<>();
orderlns.add(orderline);
item.setOrderLines(orderlns);
Customer customer = new Customer();
customer.setId(1234);
customer.setName("Tanusha");
customer.setMobile_no(Long.valueOf("9609"));
customer.setAddress("u-86, garia");
orderline.setOrders(order);
List<Orderline> orderLinesList = new ArrayList<>();
orderLinesList.add(orderline);
order.setOrderlines(orderLinesList);
order.setCustomer(customer);
List<Orders> orderList = new ArrayList<>();
orderList.add(order);
customer.setOrders(orderList);
Card_payment cp = new Card_payment();
cp.setAmount(200);
cp.setCard_expiry_date("2019/05/05");
cp.setCard_type("visa");
cp.setIssuing_bank("SBI");
cp.setOrder(order);
order.setCard_payment(cp);
entityManager.merge(order);
try {
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
}
}
}
I am trying to return json from these two entity classes.
Questions.java
#Entity
public class Questions {
#Id
#Column(name = "id")
private int id;
#Column(name = "question")
private String question;
#Column(name = "type")
private String type;
#Column(name = "description")
private String description;
#Column(name = "param")
private String param;
#Column(name = "maxlength")
private int maxlength;
#Column(name = "dependency")
private String dependency;
#OneToMany(mappedBy = "questions",targetEntity = Answers.class, cascade = CascadeType.ALL)
private Set<Answers> answers = new HashSet<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public int getMaxlength() {
return maxlength;
}
public void setMaxlength(int maxlength) {
this.maxlength = maxlength;
}
public String getDependency() {
return dependency;
}
public Set<Answers> getAnswers() {
return answers;
}
public void setAnswers(Set<Answers> answers) {
this.answers = new HashSet<>(answers);
for(Answers answers1:answers){
answers1.setQuestions(this);
}
}
public void setDependency(String dependency) {
this.dependency = dependency;
}
}
Answers.java
#Entity
public class Answers {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
#Column(name = "ans_label")
private String ans_label;
#Column(name = "ans_value")
private int ans_value;
#Column(name = "ans_weightage")
private int ans_weightage;
#Column(name = "is_default")
private int is_default;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "ques_id", nullable = false)
private Questions questions;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAns_label() {
return ans_label;
}
public void setAns_label(String ans_label) {
this.ans_label = ans_label;
}
public int getAns_value() {
return ans_value;
}
public void setAns_value(int ans_value) {
this.ans_value = ans_value;
}
public int getAns_weightage() {
return ans_weightage;
}
public void setAns_weightage(int ans_weightage) {
this.ans_weightage = ans_weightage;
}
public int getIs_default() {
return is_default;
}
public void setIs_default(int is_default) {
this.is_default = is_default;
}
public Questions getQuestions() {
return questions;
}
public void setQuestions(Questions questions) {
this.questions = questions;
}
}
my controller looks like this.
SaveApiController
#RequestMapping("/getData")
public #ResponseBody List<Questions> getData(){
List<Questions> questionss=saveApiServices.getQuestions();
return questionss;
}
The json result i am currently getting has bunch of repeated values.
[{"id":1,"question":"१. व्यक्तिको पुरा नाम थर?", "type":"input_edittext",
"description":"","param":"smalltext","maxlength":20,"dependency":"",
"answers":
[{"id":0,"ans_label":"मुली","ans_value":1,"ans_weightage":0,"is_default":0,
"questions":{"id":1,"question":"१. व्यक्तिको पुरा नाम थर?",
"type":"input_edittext","description":"","param":"smalltext","maxlength":20
,"dependency":"","answers":[{"id":0,"ans_label":"मुली","ans_value":1,
"ans_weightage":0,"is_default":0,"questions":{"id":1,
"question":"१. व्यक्तिको पुरा नाम थर ?","type":"input_edittext",
"description":"","param":"smalltext","maxlength":20,"dependency":"",
"answers":[{"id":0,"ans_label":"मुली",
"ans_value":1,"ans_weightage":0,"is_default":0,"questions":{"id":1,
"question":"१. व्यक्तिको पुरा नाम थर ?","type":"input_edittext",
"description":"","param":"smalltext","maxlength":20,"dependency":"",
my database has only one row inserted. and on my controller there is only one list of questions found. but whenever json output is thrown it repeats a lot of same rows like in the above json sample.
what might be the problems? if you can't find the complete solution can you please suggest me the reason behind the duplication of the same values in json format?
Jackson is getting in a loop here. Your Questions class has a link to Answers and that class refers back to Questions.
Solution
Mark the questions field or the getter in the Answers class as #JsonIgnored.
You can try #JsonManagedReference and #JsonBackReference annotations
For Jackson to work well, one of the two sides of the relationship should not be serialized, in order to avoid the infite loop that causes your stackoverflow error.
#OneToMany(mappedBy = "questions",targetEntity = Answers.class, cascade = CascadeType.ALL)
#JsonManagedReference
private Set<Answers> answers = new HashSet<>();
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "ques_id", nullable = false)
#JsonBackReference
private Questions questions;
Or
If not interested in getting some entity data just use #JsonIgnore in any one of the class
i have two entity classes named Qa.java and Answeres.java
my Qa entity consists of lists of answers.
Qa.Java
#Entity
#Table(name = "qa")
public class Qa {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private int id;
private String question;
private String type;
private String description;
private String param;
private int maxlength;
#OneToMany(mappedBy = "qa", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Answers> answersList = new ArrayList<>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public int getMaxlength() {
return maxlength;
}
public void setMaxlength(int maxlength) {
this.maxlength = maxlength;
}
public List<Answers> getAnswersList() {
return answersList;
}
public void setAnswersList(List<Answers> answersList) {
this.answersList = answersList;
}
}
Answers.java
#Entity
#Table(name = "answers")
public class Answers {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String ans_label;
private int ans_value;
private int ans_weightage;
private int is_default;
#ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "question_id", referencedColumnName = "id",nullable = false)
private Qa qa;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAns_label() {
return ans_label;
}
public void setAns_label(String ans_label) {
this.ans_label = ans_label;
}
public int getAns_value() {
return ans_value;
}
public void setAns_value(int ans_value) {
this.ans_value = ans_value;
}
public int getAns_weightage() {
return ans_weightage;
}
public void setAns_weightage(int ans_weightage) {
this.ans_weightage = ans_weightage;
}
public int getIs_default() {
return is_default;
}
public void setIs_default(int is_default) {
this.is_default = is_default;
}
public Qa getQa() {
return qa;
}
public void setQa(Qa qa) {
this.qa = qa;
}
}
My controller from where i am trying to insert data.
TableDataController.java
#Controller
public class TabletDataController {
#Autowired
QaRepository qaRepository;
#RequestMapping(value = "/saveApiData", method = RequestMethod.GET)
public void saveApiData(){
Qa qa = new Qa();
qa.setParam("");
qa.setType("input_spinner");
qa.setDescription("");
qa.setQuestion("व्यक्तिको पहिलो नाम ?");
ArrayList<Answers> answersArrayList = new ArrayList<>();
Answers answers = new Answers();
answers.setAns_label("नेपाली");
answers.setAns_value(1);
answers.setAns_weightage(0);
answers.setIs_default(0);
answersArrayList.add(answers);
qa.setAnswersList(answersArrayList);
qaRepository.save(qa);
}
}
my qaRepository extends JpaRepository. so whenever i call this api i get an error of com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'question_id' cannot be null
what am i doing wrong?
You have a bidirectional OneToMany relationship, so you need to manually maintain both sides of the relationship. Here you are only setting the Qa side with qa.setAnswersList(answersArrayList);
You need to set the other side of your relationship manually. add:
answers.setQa(qa);
before you save your list
code as follow
public void saveApiData(){
Qa qa = new Qa();
qa.setParam("");
qa.setType("input_spinner");
qa.setDescription("");
qa.setQuestion("व्यक्तिको पहिलो नाम ?");
ArrayList<Answers> answersArrayList = new ArrayList<>();
Answers answers = new Answers();
answers.setAns_label("नेपाली");
answers.setAns_value(1);
answers.setAns_weightage(0);
answers.setIs_default(0);
answers.setQa(qa);
answersArrayList.add(answers);
qa.setAnswersList(answersArrayList);
qaRepository.save(qa);
}
when you save.you should Cascade save.Your annotations configure the relationship of the associated tables but also to associate them when they are saved
Goal: To impolement an #Entity where the id is a compound primary key using #EmbededId.
Problem: Based on my current implementation, I am getting the following result:
[
{
"id": 1,
"name": "Recipe 1",
"instruction": "Test Instruction",
"note": "Note 1",
"show": true,
"createDate": null,
"modify_date": null,
"ingredient": [
{},
{}
]
}
]
but I want to have this:
[
{
"id": 1,
"name": "Recipe 1",
"instruction": "Test Instruction",
"note": "Note 1",
"show": true,
"createDate": null,
"modify_date": null,
"ingredient": [
{ingredient_id: 1,
amount: 10},
{ingredient_id: 2,
amount: 20}
]
}
]
Can someone please help me too see where I have done wrong in my recipeIngredient class? Thanks in advance.
The following are my implementation:
The schema:
RecipeIngredientId.java
#Embeddable
public class RecipeIngredientId implements Serializable {
#Column(name = "recipe_id", nullable = false)
private int recipeId;
#Column(name = "ingredient_id", nullable = false)
private int ingredientId;
public RecipeIngredientId() {}
public RecipeIngredientId(int recipeId, int ingredientId) {
this.recipeId = recipeId;
this.ingredientId = ingredientId;
}
}
RecipeIngredient.java
#Entity
#Table(name = "recipe_ingredient")
public class RecipeIngredient implements Serializable
{
#EmbeddedId
private RecipeIngredientId id;
#ManyToOne
#JoinColumn(name="ingredient_id", insertable = false, updatable = false)
private Ingredient ingredient;
#ManyToOne
#JoinColumn(name = "recipe_id", insertable = false, updatable = false)
private Recipe recipe;
private double amount;
public RecipeIngredient() {}
public RecipeIngredient(Recipe recipe, Ingredient ingredient, double amount){
this.recipe = recipe;
this.ingredient = ingredient;
this.amount = amount;
}
}
Recipe.java:
#Entity
public class Recipe {
private int id;
#NotNull
private String name;
private String instruction;
private String note;
#NotNull
private boolean show;
#CreationTimestamp
#Temporal(TemporalType.DATE)
#Column(name = "create_date")
private Date createDate;
#UpdateTimestamp
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "modify_date")
private Date modify_date;
private Set<RecipeIngredient> recipeIngredients;
public Recipe() {}
public Recipe(String name, String instruction, String note, boolean show) {
this.name = name;
this.instruction = instruction;
this.note = note;
this.show = show;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
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 String getInstruction() {
return instruction;
}
public void setInstruction(String instruction) {
this.instruction = instruction;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public boolean isShow() {
return show;
}
public void setShow(boolean show) {
this.show = show;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModify_date() {
return modify_date;
}
public void setModify_date(Date modify_date) {
this.modify_date = modify_date;
}
#OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
public Set<RecipeIngredient> getIngredient() {
return recipeIngredients;
}
public void setIngredient(Set<RecipeIngredient> recipeIngredients) {
this.recipeIngredients = recipeIngredients;
}
}
Ingredient.java
#Entity
public class Ingredient {
private int id;
#NotNull
#Column(unique=true)
private String name;
private Set<RecipeIngredient> recipeIngredients;
public Ingredient() {}
public Ingredient(String name) {
this.name = name;
}
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
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;
}
#OneToMany(mappedBy = "ingredient", cascade = CascadeType.ALL)
public Set<RecipeIngredient> getRecipeIngredients() {
return recipeIngredients;
}
public void setRecipeIngredients(Set<RecipeIngredient> recipeIngredients) {
this.recipeIngredients = recipeIngredients;
}
}
This is a case of "derived identity". RecipeIngredient should look like this:
#Entity
#Table(name = "recipe_ingredient")
public class RecipeIngredient implements Serializable
{
#EmbeddedId
private RecipeIngredientId id;
#MapsId("ingredientId") // maps ingredientId attribute of embedded id
#ManyToOne
#JoinColumn(name="ingredient_id", insertable = false, updatable = false)
private Ingredient ingredient;
#MapsId("recipeId") // maps recipeId attribute of embedded id
#ManyToOne
#JoinColumn(name = "recipe_id", insertable = false, updatable = false)
private Recipe recipe;
private double amount;
public RecipeIngredient() {}
public RecipeIngredient(Recipe recipe, Ingredient ingredient, double amount){
this.recipe = recipe;
this.ingredient = ingredient;
this.amount = amount;
}
}
Note the MapsId annotations on the two fields whose primary keys make up the entity's composite key.
Derived identities are discussed in the JPA 2.1 spec in section 2.4.1.