I am facing problem while inserting. I want to save the details in result table without saving the foreign key parameters in parent table.
there are three pojo classes:
#Entity
#Table(name="course")
public class Course implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column( name="id")
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
#Column(name="course_id",nullable = false)
private String course_id;
#Column( name="course_name")
private String course_name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCourse_id() {
return course_id;
}
public void setCourse_id(String course_id) {
this.course_id = course_id;
}
public String getCourse_name() {
return course_name;
}
public void setCourse_name(String course_name) {
this.course_name = course_name;
}
**#OneToMany(fetch = FetchType.EAGER, mappedBy = "course")
private Set<Result> result = new HashSet<Result>(0);
public Set<Result> getResult() {
return this.result;
}
public void setResult(Set<Result> result) {
this.result = result;
}**
}
The second class is Student.java
#Entity
#Table(name ="student")
public class Student implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
//Attribute----------------------------------
#Id
#Column(name="id")
#GeneratedValue(strategy=GenerationType.AUTO)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//Attribute----------------------------------
#Column(name="student_id", nullable=false)
private long student_id;
public long getStudent_id() {
return student_id;
}
public void setStudent_id(long student_id) {
this.student_id = student_id;
}
//Attribute----------------------------------
#Column(name="student_name")
private String student_name;
public String getStudent_name() {
return student_name;
}
public void setStudent_name(String student_name) {
this.student_name = student_name;
}
//Attribute----------------------------------
#Column(name="student_contact_number")
private long student_contact_number;
public long getStudent_contact_number() {
return student_contact_number;
}
public void setStudent_contact_number(long student_contact_number) {
this.student_contact_number = student_contact_number;
}
//This is for the foreign key element in the Result.java POJO class
#OneToMany(fetch = FetchType.LAZY,cascade = {CascadeType.ALL}, mappedBy = "student")
private Set<Result> result = new HashSet<Result>(0);
public Set<Result> getResult() {
return this.result;
}
public void setResult(Set<Result> result) {
this.result = result;
}
}
Third is Result.java which contains the foreign keys
#Entity
#Table(name="result")
public class Result implements Serializable{
private static final long serialVersionUID = 1L;
#Id
#Column(name="id")
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Column(name="semester")
private int semester;
public int getSemester() {
return semester;
}
public void setSemester(int semester) {
this.semester = semester;
}
#Column(name="marks")
private int marks;
public int getMarks() {
return marks;
}
public void setMarks(int marks) {
this.marks = marks;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "student_id", nullable = false)
private Student student;
public Student getStudent() {
return this.student;
}
public void setStudent(Student student_id) {
this.student = student_id;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "course_id", nullable = false)
private Course course;
public Course getCourse() {
return this.course;
}
public void setCourse(Course course) {
this.course = course;
}
}
Now the code I used to insert is like this:
Session session;
Transaction t;
Query query;
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");
//#SuppressWarnings("deprecation")
SessionFactory factory=cfg.buildSessionFactory();
session=factory.openSession();
t=session.beginTransaction();
Result result;
Course cs;
Student st;
for(int i=0; i<jsrm.get(0).size(); i++)
{
result=new Result();
cs= new Course();
st=new Student();
cs.setCourse_id(jsrm.get(0).get(i).getcourse_id());
st.setStudent_id(Integer.parseInt(jsrm.get(0).get(i).getstudent_id()));
result.setSemester(Integer.parseInt(jsrm.get(0).get(i).getsemester()));
result.setMarks(Integer.parseInt(jsrm.get(0).get(i).getmarks()));
result.setCourse(cs);
result.setStudent(st);
session.save(result);
}
t.commit();//transaction is committed
session.close();
The error is
org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before
current operation: Result.course -> Course
Is there a way to store the data without saving the course and student.
Related
In my project I try yo use Spring data Jpa. My find methods(findById, findAll) works correctly, but delete and save method works with problems. Delete method delete only from duck table. Save doesn't work:
Exception in thread "main" org.springframework.orm.jpa.JpaObjectRetrievalFailureException: Unable to find springdata.entities.FrogJpa with id 2; nested exception is javax.persistence.EntityNotFoundException: Unable to find springdata.entities.FrogJpa with id 2
I have 2 entities: Frog and Duck. Every ducks have 1 Frog(OneToOne). There are problems with entities relationship?
There are my entities class:
#Entity
#Table(name = "DUCKS")
public class DuckJpa implements Serializable {
#Id
private int id;
#Column(name = "NAME")
private String name;
#Column(name = "FLY")
private String flyBehavior;
#Column(name = "QUACK")
private String quackBehavior;
#OneToOne(optional = false)
#JoinColumn(name = "FROG_ID", unique = true, nullable = false, updatable = false)
private FrogJpa frogJpa;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setFlyBehavior(String flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(String quackBehavior) {
this.quackBehavior = quackBehavior;
}
public void setFrogJpa(FrogJpa frogJpa) {
this.frogJpa = frogJpa;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getFlyBehavior() {
return flyBehavior;
}
public String getQuackBehavior() {
return quackBehavior;
}
public FrogJpa getFrogJpa() {
return frogJpa;
}
And Frog:
#Entity
#Table(name = "FROGS")
public class FrogJpa {
#OneToOne(optional = false, mappedBy = "frogJpa")
private DuckJpa duckJpa;
#Id
private int id;
#Column(name = "name")
private String name;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setDuckJpa(DuckJpa duckJpa) {
this.duckJpa = duckJpa;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public DuckJpa getDuckJpa() {
return duckJpa;
}
}
My service class:
public interface DuckService {
List<DuckJpa> findAll();
Optional<DuckJpa> findById(Integer i);
DuckJpa save(DuckJpa duckJpa);
void delete(DuckJpa duckJpa);
}
And it's implementation:
#Service("springJpaDuckService")
#Transactional
public class DuckServiceImpl implements DuckService {
#Autowired
private DuckJpaRepository duckJpaRepository;
#Transactional(readOnly = true)
public List<DuckJpa> findAll() {
return new ArrayList<>(duckJpaRepository.findAll());
}
#Override
public Optional<DuckJpa> findById(Integer i) {
return duckJpaRepository.findById(i);
}
#Override
public DuckJpa save(DuckJpa duckJpa) {
duckJpaRepository.save(duckJpa);
return duckJpa;
}
#Override
public void delete(DuckJpa duckJpa) {
duckJpaRepository.delete(duckJpa);
}
Use #OneToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY).
For more information please refer What is cascading in Hibernate?
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 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
I have three entities which form the association relationship by having composite primary keys that also foreign key of other tables. These are the implementation of these entites:
#Entity
#Table(name = "STUDENTSCOURSES", schema = "GPA")
#NamedQuery(name = "getAllStdCrs", query = "SELECT sc FROM StudentsCourses sc")
#IdClass(StudentCourseId.class)
public class StudentsCourses implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="studentID", insertable=false, updatable= false)
private int studentID;
#Id
#Column(name="crsID", insertable=false, updatable=false)
private int crsID;
#ManyToOne
#JoinColumn(name="STUDENTID")
Student student;
#ManyToOne
#JoinColumn(name="CRSID")
Course course;
public StudentsCourses() {
super();
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
public int getStudentID() {
return studentID;
}
public void setCrsID(int crsID) {
this.crsID = crsID;
}
public int getCrsID() {
return crsID;
}
}
Course entity:
#Entity
#Table(name = "COURSES", schema = "GPA")
#NamedQuery(name = "getAllCourses", query = "SELECT c FROM Course c")
public class Course implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="CRSID")
private int crsID;
private String name;
#OneToMany(mappedBy="course", fetch=FetchType.LAZY)
private Set<Assesment> assesments;
#OneToMany(mappedBy="course", fetch=FetchType.LAZY)
private Set<StudentsCourses> studentCourses;
public Course() {
super();
}
public int getCrsID() {
return crsID;
}
public void setCrsID(int crsID) {
this.crsID = crsID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAssesments(Set<Assesment> assesments) {
this.assesments = assesments;
}
public Set<Assesment> getAssesments() {
return assesments;
}
public void setStudentCourses(Set<StudentsCourses> studentCourses) {
this.studentCourses = studentCourses;
}
public Set<StudentsCourses> getStudentCourses() {
return studentCourses;
}
}
Student Entity:
#Entity
#Table(name = "STUDENTS", schema = "GPA")
#NamedQuery(name = "getAllStudents", query = "SELECT s FROM Student s")
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int studentID;
private String studentName;
#OneToMany(mappedBy="student", fetch = FetchType.LAZY)
private Set<Assesment> assesments;
#OneToMany(mappedBy="student", fetch = FetchType.LAZY)
private Set<StudentsCourses> studentCourses;
public Student() {
super();
}
public int getStudnetID() {
return studentID;
}
public void setStudnetID(int stdID) {
this.studentID = stdID;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentName() {
return studentName;
}
public void setAssesments(Set<Assesment> assesments) {
this.assesments = assesments;
}
public Set<Assesment> getAssesments() {
return assesments;
}
public void setStudentCourses(Set<StudentsCourses> studentCourses) {
this.studentCourses = studentCourses;
}
public Set<StudentsCourses> getStudentCourses() {
return studentCourses;
}
}
When I try to lanuch the program I am getting following error:
[4/5/13 0:30:15:243 EDT] 00000028 webapp E com.ibm.ws.webcontainer.webapp.WebApp logServletError SRVE0293E: [Servlet Error]-[com.gpa.app.servlet.LoginServlet]: <openjpa-2.1.1-SNAPSHOT-r422266:1141200 fatal user error> org.apache.openjpa.persistence.ArgumentException: Field "com.gpa.app.entities.Course.studentCourses" cannot declare that it is mapped by another field. Its mapping strategy (org.apache.openjpa.jdbc.meta.strats.HandlerFieldStrategy) does not support mapping by another field.
What could be the cause of the prob. Appreciate your help.
So the problem was in my #Id classes. In that class I didn't implemented equal and hash code method and also didn't implemented Serializable. After done that everything worked smoothly. Thanks to Eelke, he gave me the idea to try in different version and it helped me to find out the cause.
My modified code in looks like this:
public class StudentCourseId implements Serializable{
private static final long serialVersionUID = 1L;
private int studentID;
private int crsID;
public StudentCourseId() {
}
public StudentCourseId(int studentID, int crsID) {
this.studentID = studentID;
this.crsID = crsID;
}
public void setStudentID(int studentID) {
this.studentID = studentID;
}
public int getStudentID() {
return studentID;
}
public void setCrsID(int crsID) {
this.crsID = crsID;
}
public int getCrsID() {
return crsID;
}
public int hashCode() {
return studentID + crsID;
}
public boolean equals(Object o) {
return ((o instanceof StudentCourseId)
&& studentID == ((StudentCourseId) o).getStudentID() && crsID == ((StudentCourseId) o)
.getCrsID());
}
}
public int getCrsID() {
return crsID;
}
}
Hope it helps for someone in the future.
Thanks,
Sas
I'm trying to create manytomany realation between Student and Teaching Course using Composite Primary key:
my classes:
#Entity
#Table(name="Student_mtm_cId")
public class Student {
private String id;
private Set<StudentTClass> teachingClasses = new HashSet<StudentTClass>();
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.student")
public Set<StudentTClass> getTeachingClasses() {
return teachingClasses;
}
public void setTeachingClasses(Set<StudentTClass> teachingClasses) {
this.teachingClasses = teachingClasses;
}
public void addStudentToClass(TeachingClass teachingClass){
StudentTClass studentTClass = new StudentTClass();
studentTClass.setStudent(this);
studentTClass.setTeachingClass(teachingClass);
teachingClasses.add(studentTClass);
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#Id #GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
#Column(name = "student_id", nullable = false)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
//all other setters and getters and isequal/hashCode omitted.
}
TeachingClass:
#Entity
#Table(name="TechingClass_MTM")
public class TeachingClass {
private String id;
private String name;
private String description;
private Set<StudentTClass> teachingClasses = new HashSet<StudentTClass>();
public TeachingClass(){}
public TeachingClass(String name, String description) {
super();
this.name = name;
this.description = description;
}
public void addStudentToClass(Student student){
StudentTClass studentTClass = new StudentTClass();
studentTClass.setStudent(student);
studentTClass.setTeachingClass(this);
teachingClasses.add(studentTClass);
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.teachingClass")
public Set<StudentTClass> getTeachingClasses() {
return teachingClasses;
}
public void setTeachingClasses(Set<StudentTClass> teachingClasses) {
this.teachingClasses = teachingClasses;
}
public void setDescription(String description) {
this.description = description;
}
#Id #GeneratedValue(generator="system-uuid")
#GenericGenerator(name="system-uuid", strategy = "uuid")
#Column(name = "teachingClass_id", nullable = false)
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Collection Objects:
#Entity
#Table(name = "student_TClass_MTM")
#AssociationOverrides({
#AssociationOverride(name = "pk.student", joinColumns = #JoinColumn(name = "student_id")),
#AssociationOverride(name = "pk.teachingClass", joinColumns = #JoinColumn(name = "teachingClass_id"))
})
public class StudentTClass {
#EmbeddedId
private StudentTClassPK pk = new StudentTClassPK();
public StudentTClassPK getPk() {
return pk;
}
public void setPk(StudentTClassPK pk) {
this.pk = pk;
}
public StudentTClass() {}
#Transient
public Student getStudent(){
return this.pk.getStudent();
}
#Transient
public TeachingClass getTeachingClass(){
return this.pk.getTeachingClass();
}
public void setStudent(Student student){
this.pk.setStudent(student);
}
public void setTeachingClass(TeachingClass teachingClass){
this.pk.setTeachingClass(teachingClass);
}
}
Now The primary Key:
#Embeddable
public class StudentTClassPK implements Serializable{
private static final long serialVersionUID = -7261887879839337877L;
private Student student;
private TeachingClass teachingClass;
#ManyToOne
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
#ManyToOne
public TeachingClass getTeachingClass() {
return teachingClass;
}
public void setTeachingClass(TeachingClass teachingClass) {
this.teachingClass = teachingClass;
}
public StudentTClassPK(Student student, TeachingClass teachingClass) {
this.student = student;
this.teachingClass = teachingClass;
}
public StudentTClassPK() {}
}
When I'm trying to Persist Student I got the following error:
Caused by: org.hibernate.MappingException: Could not determine type for: com.vanilla.objects.Student, at table: student_TClass_MTM, for columns: [org.hibernate.mapping.Column(student)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:306)
at org.hibernate.tuple.PropertyFactory.buildStandardProperty(PropertyFactory.java:143)
at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:68)
at org.hibernate.mapping.Component.buildType(Component.java:184)
at org.hibernate.mapping.Component.getType(Component.java:177)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:290)
at org.hibernate.mapping.RootClass.validate(RootClass.java:236)
at org.hibernate.cfg.Configuration.validate(Configuration.java:1362)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1865)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:855)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:774)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)
... 51 more
What am I doing wrong?
I solved this issue. I mapped Getter instead of field.
public class StudentTClass {
//#EmbeddedId
private StudentTClassPK pk = new StudentTClassPK();
#EmbeddedId
public StudentTClassPK getPk() {
return pk;
}
If you can, I'd seriously suggest removing the composite keys. Worth with simple primary keys can both make a lot of problems go away and simplify your code. I have used composite keys in a database in the past because I had no ability to modify the db. Unfortunately I don't have the code. But I do remember it took some work to get it all working correctly. Sorry, can't help more.