I'm just learning to develop a REST application using JAXB and JPA. I'm stuck in weird problem and I have no clue what to search for.
I have these two classes:
package clinic.model;
import java.io.Serializable;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlList;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlInverseReference;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* The persistent class for the patients database table.
*
*/
#Entity
#Table(name="patients")
#NamedQuery(name="Patient.findAll", query="SELECT p FROM Patient p")
#XmlRootElement
public class Patient implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String address;
private String area;
#Temporal(TemporalType.DATE)
private Date dob;
private BigDecimal mobile;
private String name;
private String sex;
//bi-directional many-to-one association to Prescription
#OneToMany(mappedBy="patient")
private List<Prescription> prescriptions;
public Patient() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getArea() {
return this.area;
}
public void setArea(String area) {
this.area = area;
}
public Date getDob() {
return this.dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public BigDecimal getMobile() {
return this.mobile;
}
public void setMobile(BigDecimal mobile) {
this.mobile = mobile;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
#XmlList
public List<Prescription> getPrescriptions() {
return this.prescriptions;
}
public void setPrescriptions(List<Prescription> prescriptions) {
this.prescriptions = prescriptions;
}
public Prescription addPrescription(Prescription prescription) {
getPrescriptions().add(prescription);
prescription.setPatient(this);
return prescription;
}
public Prescription removePrescription(Prescription prescription) {
getPrescriptions().remove(prescription);
prescription.setPatient(null);
return prescription;
}
}
And
package clinic.model;
import java.io.Serializable;
import javax.persistence.*;
import org.eclipse.persistence.oxm.annotations.XmlInverseReference;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* The persistent class for the prescriptions database table.
*
*/
#Entity
#Table(name="prescriptions")
#NamedQuery(name="Prescription.findAll", query="SELECT p FROM Prescription p")
public class Prescription implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
#Temporal(TemporalType.DATE)
private Date date;
private BigDecimal fee;
#Temporal(TemporalType.DATE)
private Date followup;
private String treatment;
//bi-directional many-to-one association to Patient
#ManyToOne(fetch=FetchType.LAZY)
private Patient patient;
//bi-directional many-to-many association to Diagnosis
#ManyToMany
#JoinTable(
name="prescriptions_diagnoses"
, joinColumns={
#JoinColumn(name="pid")
}
, inverseJoinColumns={
#JoinColumn(name="did")
}
)
private List<Diagnosis> diagnoses;
//bi-directional many-to-one association to PrescriptionDrug
#OneToMany(mappedBy="prescription")
private List<PrescriptionDrug> prescriptionsDrugs;
//bi-directional many-to-many association to Vaccine
#ManyToMany(mappedBy="prescriptions")
private List<Vaccine> vaccines;
public Prescription() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getDate() {
return this.date;
}
public void setDate(Date date) {
this.date = date;
}
public BigDecimal getFee() {
return this.fee;
}
public void setFee(BigDecimal fee) {
this.fee = fee;
}
public Date getFollowup() {
return this.followup;
}
public void setFollowup(Date followup) {
this.followup = followup;
}
public String getTreatment() {
return this.treatment;
}
public void setTreatment(String treatment) {
this.treatment = treatment;
}
public Patient getPatient() {
return this.patient;
}
public void setPatient(Patient patient) {
this.patient = patient;
}
public List<Diagnosis> getDiagnoses() {
return this.diagnoses;
}
public void setDiagnoses(List<Diagnosis> diagnoses) {
this.diagnoses = diagnoses;
}
public List<PrescriptionDrug> getPrescriptionsDrugs() {
return this.prescriptionsDrugs;
}
public void setPrescriptionsDrugs(List<PrescriptionDrug> prescriptionsDrugs) {
this.prescriptionsDrugs = prescriptionsDrugs;
}
public PrescriptionDrug addPrescriptionsDrug(PrescriptionDrug prescriptionsDrug) {
getPrescriptionsDrugs().add(prescriptionsDrug);
prescriptionsDrug.setPrescription(this);
return prescriptionsDrug;
}
public PrescriptionDrug removePrescriptionsDrug(PrescriptionDrug prescriptionsDrug) {
getPrescriptionsDrugs().remove(prescriptionsDrug);
prescriptionsDrug.setPrescription(null);
return prescriptionsDrug;
}
public List<Vaccine> getVaccines() {
return this.vaccines;
}
public void setVaccines(List<Vaccine> vaccines) {
this.vaccines = vaccines;
}
}
When I have a patient entry in the database, the service is able to map entities into XML/JSON. But when I add an associating prescription entry, Glassfish throws error 500.
What could be the problem?
I'm using GlassFish 4.0 and EclipseLink 2.5.1. IDE is Eclipse Luna.
Solution found at http://blog.bdoughan.com/2010/07/jpa-entities-to-xml-bidirectional.html
The exception can be seen if a string is returned instead of the POJO object and the marshaling is done manually.
Related
I have an issue in joining two tables column. I have two entities Status Report and Employee. and I want the data of employee inside StatusReport.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
#Entity
#Table(name="statusreport")
public class StatusReport {
private BigInteger COMPLIANCEID;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger STATUSRPTID;
private BigInteger EMPID;
private String COMMENTS;
private Date CREATEDDATE;
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinTable(name = "Employees")
#JoinColumn(name = "EMPID")
private Employees employee;
public StatusReport(){
}
public StatusReport(BigInteger COMPLIANCEID,BigInteger EMPID,
String COMMENTS,Date CREATEDDATE,BigInteger DEPARTMENT_ID){
this.COMPLIANCEID=COMPLIANCEID;
this.EMPID=EMPID;
this.COMMENTS=COMMENTS;
this.CREATEDDATE=CREATEDDATE;
this.DEPARTMENT_ID=DEPARTMENT_ID;
}
public BigInteger getCOMPLIANCEID() {
return COMPLIANCEID;
}
public void setCOMPLIANCEID(BigInteger COMPLIANCEID) {
this.COMPLIANCEID = COMPLIANCEID;
}
public BigInteger getSTATUSRPTID() {
return STATUSRPTID;
}
public void setSTATUSRPTID(BigInteger STATUSRPTID) {
this.STATUSRPTID = STATUSRPTID;
}
public BigInteger getEMPID() {
return EMPID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public String getCOMMENTS() {
return COMMENTS;
}
public void setCOMMENTS(String COMMENTS) {
this.COMMENTS = COMMENTS;
}
public Date getCREATEDDATE() {
return CREATEDDATE;
}
public void setCREATEDDATE(Date CREATEDDATE) {
this.CREATEDDATE = CREATEDDATE;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public Employees getEmployee() {
return employee;
}
public void setEmployee(Employees employee) {
this.employee = employee;
}
}
Another class is the employee:
package com.sl.ems.models;
import com.sl.ems.utils.Utils;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
#Entity
public class Employees {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger EMPID;
private String FIRSTNAME;
private String LASTNAME;
private Date DOB;
private String EMAIL;
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinTable(name = "Department")
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;
public Employees(){
}
public Employees(String FIRSTNAME,String LASTNAME,Date DOB,String EMAIL,BigInteger DEPARTMENT_ID){
this.FIRSTNAME=FIRSTNAME;
this.LASTNAME=LASTNAME;
this.DOB=DOB;
this.EMAIL=EMAIL;
this.DEPARTMENT_ID=DEPARTMENT_ID;
}
public BigInteger getEMPID() {
return EMPID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public String getFIRSTNAME() {
return FIRSTNAME;
}
public void setFIRSTNAME(String FIRSTNAME) {
this.FIRSTNAME = FIRSTNAME;
}
public String getLASTNAME() {
return LASTNAME;
}
public void setLASTNAME(String LASTNAME) {
this.LASTNAME = LASTNAME;
}
public Date getDOB() {
return DOB;
}
public void setDOB(Date DOB) {
this.DOB = DOB;
}
public String getEMAIL() {
return EMAIL;
}
public void setEMAIL(String EMAIL) {
this.EMAIL = EMAIL;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
As you can see employee entity itself have some other joins on other tables. Which is a deparment table.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
#Entity
public class Department {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger DEPARTMENT_ID;
private String DEPARTMENT_NM;
public Department(){
}
public Department(String DEPARTMENT_NM){
this.DEPARTMENT_NM=DEPARTMENT_NM;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public String getDEPARTMENT_NM() {
return DEPARTMENT_NM;
}
public void setDEPARTMENT_NM(String DEPARTMENT_NM) {
this.DEPARTMENT_NM = DEPARTMENT_NM;
}
}
When I join Status Report with Employee I get Sql exception. But strangly when I remove join of Department in Employee entity table then I get the result.
Can someone please help if I am missing anything?
Looks like your mapping is not correct. Also verify you have a EMPID column.
You don't need to use the #JoinTable annotation in your case.
StatusReport - removed private BigInteger EMPID; as it is ued n joining
#Entity
#Table(name="statusreport")
public class StatusReport {
private BigInteger COMPLIANCEID;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger STATUSRPTID;
private String COMMENTS;
private Date CREATEDDATE;
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinColumn(name = "EMPID")
private Employees employee;
//others methods
Employee - removed private BigInteger DEPARTMENT_ID; as it is ued n joining
#Entity
public class Employees {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger EMPID;
private String FIRSTNAME;
private String LASTNAME;
private Date DOB;
private String EMAIL;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;
Well taking help from above post. I made few other changes in my code. As I could not manage to remove the field completely from my entity class so I made it Transient and set its property from the join column object method. So my class are as follows.
Employee class is as follows.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
#Entity
public class Employees {
/**
Author: Puneet Kumar Bahuguna
Year: DEC 2020
Project: SimplyLearn EMS
Description: This Entity class mapped to the employees table in the database.
**/
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger EMPID;
private String FIRSTNAME;
private String LASTNAME;
private Date DOB;
private String EMAIL;
#Transient
private BigInteger DEPARTMENT_ID;
#OneToOne
#JoinColumn(name = "DEPARTMENT_ID")
private Department department;
public Employees(){
}
public Employees(BigInteger EMPID){
this.EMPID=EMPID;
}
public Employees(String FIRSTNAME,String LASTNAME,Date DOB,String EMAIL,Department department){
this.FIRSTNAME=FIRSTNAME;
this.LASTNAME=LASTNAME;
this.DOB=DOB;
this.EMAIL=EMAIL;
this.department=department;
}
public BigInteger getEMPID() {
return EMPID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public String getFIRSTNAME() {
return FIRSTNAME;
}
public void setFIRSTNAME(String FIRSTNAME) {
this.FIRSTNAME = FIRSTNAME;
}
public String getLASTNAME() {
return LASTNAME;
}
public void setLASTNAME(String LASTNAME) {
this.LASTNAME = LASTNAME;
}
public Date getDOB() {
return DOB;
}
public void setDOB(Date DOB) {
this.DOB = DOB;
}
public String getEMAIL() {
return EMAIL;
}
public void setEMAIL(String EMAIL) {
this.EMAIL = EMAIL;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
}
StatusReport class is as follows.
package com.sl.ems.models;
import javax.persistence.*;
import java.math.BigInteger;
import java.util.Date;
#Entity
#Table(name="statusreport")
public class StatusReport {
/**
Author: Puneet Kumar Bahuguna
Year: DEC 2020
Project: SimplyLearn EMS
Description: This Entity class mapped to the statusreport table in the database.
**/
private BigInteger COMPLIANCEID;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private BigInteger STATUSRPTID;
private String COMMENTS;
private Date CREATEDDATE;
private BigInteger DEPARTMENT_ID;
#Transient
private BigInteger EMPID;
#OneToOne
#JoinColumn(name = "EMPID")
private Employees employee;
public StatusReport(){
}
public StatusReport(String COMMENTS,Date CREATEDDATE){
}
public StatusReport(BigInteger COMPLIANCEID,String COMMENTS,Date CREATEDDATE,
BigInteger DEPARTMENT_ID,Employees employee){
this.COMPLIANCEID=COMPLIANCEID;
this.COMMENTS=COMMENTS;
this.CREATEDDATE=CREATEDDATE;
this.DEPARTMENT_ID=DEPARTMENT_ID;
this.employee=employee;
}
public BigInteger getCOMPLIANCEID() {
return COMPLIANCEID;
}
public void setCOMPLIANCEID(BigInteger COMPLIANCEID) {
this.COMPLIANCEID = COMPLIANCEID;
}
public void setEMPID(BigInteger EMPID) {
this.EMPID = EMPID;
}
public BigInteger getEMPID() {
return EMPID;
}
public BigInteger getSTATUSRPTID() {
return STATUSRPTID;
}
public void setSTATUSRPTID(BigInteger STATUSRPTID) {
this.STATUSRPTID = STATUSRPTID;
}
public String getCOMMENTS() {
return COMMENTS;
}
public void setCOMMENTS(String COMMENTS) {
this.COMMENTS = COMMENTS;
}
public Date getCREATEDDATE() {
return CREATEDDATE;
}
public void setCREATEDDATE(Date CREATEDDATE) {
this.CREATEDDATE = CREATEDDATE;
}
public BigInteger getDEPARTMENT_ID() {
return DEPARTMENT_ID;
}
public void setDEPARTMENT_ID(BigInteger DEPARTMENT_ID) {
this.DEPARTMENT_ID = DEPARTMENT_ID;
}
public Employees getEmployee() {
return employee;
}
public void setEmployee(Employees employee) {
this.employee = employee;
}
}
Please also note for example while you are saving a StatusReport object by using save method of jpa you will have to set the EMPID through getEmployee().getEMPID()
I want a Bi-Directional mapping on my 2 Entities(PersonDetail,
PassportDetail) but it seems that it doesn't work fine. I want that
PersonDetail has a PassportId and PassportDetail has a PersonId as well.
My PersonDetail java Code
#Entity
#Table(name="persondetail")
public class PersonDetail {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="person_id")
private int id;
#Column(name="person_name")
private String name;
#Column(name="person_phone")
private long phone;
#OneToOne(mappedBy="person",cascade=CascadeType.ALL)
#JoinColumn(name="passport_id")
private PassportDetail passport;
public PassportDetail getPassport() {
return passport;
}
public void setPassport(PassportDetail passport) {
this.passport = passport;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getPhone() {
return phone;
}
public void setPhone(long phone) {
this.phone = phone;
}
#Column(name="passport_id")
private int passort_id;
public int getPassort_id() {
return passort_id;
}
public void setPassort_id(int passort_id) {
this.passort_id = passort_id;
}
}
Here is my PassportDetail Java Code
#Entity
#Table(name="PassportDetail")
public class PassportDetail {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="passport_id")
private int id;
#Column(name="passport_number")
private String passportNumber;
#Column(name="country_name")
private String country;
#Column(name="issue_date")
#Temporal(TemporalType.DATE)
private Date date;
#OneToOne
#JoinColumn(name="person_id")
private PersonDetail person;
public String getPassportNumber() {
return passportNumber;
}
public void setPassportNumber(String passportNumber) {
this.passportNumber = passportNumber;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public PersonDetail getPerson() {
return person;
}
public void setPerson(PersonDetail person) {
this.person = person;
}
}
Here is the Output in MySql
Here is the Output of Both table as you can clearly see the problem i.e PersonDetail has a column named passport_id but it dosesn't have any value
Here is the insertion code
public class MappingMain {
public static void main(String[] args) {
PersonDetail person=new PersonDetail();
PassportDetail passport = new PassportDetail();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd");
person.setName("Ankit");
person.setPhone(790148565);
passport.setCountry("india");
try {
passport.setDate(sdf.parse("2018-04-15"));
}
catch(Exception e)
{
}
passport.setPassportNumber("QUJMZ123");
passport.setPerson(person);
person.setPassport(passport);
PersonDao dao=new PersonDao();
dao.save(person);
}
Here is the DAO class
public class MappingDao {
SessionFactory sf=Util.getSessionFactory();
public void save(UserDemo user)
{
Session session=sf.openSession();
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
session.close();
}
}
After Searching stack overflow I came to this
Can I use hibernate query language for entities not mapped to a table?
But recently I was making a small project where the two entities were not mapped by any Mapped Annotations and still I got the result for the query.
So I am confused as the posts say it is not possible to query on Non-Mapped Entities.
Customer
package com.mayank.bitmesra.pojo;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
public class Customer {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String customerId;
private String name;
private String phoneNumber;
#Temporal(TemporalType.DATE)
private Date dateOfBirth;
#Temporal(TemporalType.DATE)
private Date createdDate;
//for rolling back of Data
//using date as such of now
#Temporal(TemporalType.DATE)
private Date updatedOn;
//for picking up only the data that is most recent
//like a customer can have save with same customer id
//but has different address as his address might have changed up in near future
//will try to handle this in near future
/* #Temporal
private Date lastPickedUpDate;*/
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
#Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", phoneNumber=" + phoneNumber + "]";
}
public Date getUpdatedOn() {
return updatedOn;
}
public void setUpdatedOn(Date updatedOn) {
this.updatedOn = updatedOn;
}
#PrePersist
protected void onCreate() {
createdDate = new Date();
}
#PreUpdate
protected void onUpdate() {
updatedOn = new Date();
}
}
OrderDetails
package com.mayank.bitmesra.pojo;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class OrderDetails {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private long id;
private String customerId;
private String orderId;
private String orderName;
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
}
OrderDetailsDAOImpl
#Repository
#Transactional
public class OrderDetailsDAOImpl implements OrderDetailsDAO{
#PersistenceContext
EntityManager entityManager;
#Override
public List getAllOrderDetails() {
// return entityManager.createQuery("Select order from OrderDetails order ").getResultList();
return entityManager.createQuery("Select customer.name from OrderDetails order inner join Customer customer on order.customerId=customer.customerId").getResultList();
}
I think you are confused . #Entity is the annotation used by HQL to identify the so called mapped entities. Both of the entities are annotated by them.
I'm not understanding how to do something that is probably very easy to do. I have a table named "Composer". A "Composer" can have many compositions ("Composition" table). I get the following error when I run this through Spring Boot:
19:11:40 web.1 | Caused by: org.hibernate.AnnotationException:
mappedBy reference an unknown target entity property:
com.zack.music.domain.Composition.composition in com.zack.music.domain.Composer.compositions
Below are my entity classes. What am I doing wrong here?
package com.zack.music.domain;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Date;
import java.util.*;
#Entity
public class Composer implements Serializable {
#Id
private String name;
private Date birth;
private Date death;
#OneToMany(mappedBy="composition")
private List<Composition> compositions;
protected Composer() { }
public Composer(String name, Date birth, Date death) {
this.name = name;
this.birth = birth;
this.death = death;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Date getDeath() {
return death;
}
public void setDeath(Date death) {
this.death = death;
}
public List<Composition> getCompositions() {
return compositions;
}
public void setCompositions(List<Composition> compositions) {
this.compositions = compositions;
}
}
#Entity
public class Composition implements Serializable {
#Id
#Column(nullable = false)
private String name;
#ManyToOne
private Composer composer;
protected Composition() { }
public Composition(String name, Composer composer) {
this.name = name;
this.composer = composer;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Composer getComposer() {
return composer;
}
public void setComposer(Composer composer) {
this.composer = composer;
}
}
mappedBy is telling hibernate the property name on the related entity that owns the relationship. There is no property named 'composition' on the related entity: Composition. You probably just meant for the value of mappedBy to be "composer".
I was able to solve it using #ElementCollection. Java Persistence/ElementCollection helped me figure it out. I also filled in the "name" attributes on all of my tables and columns which I think helped identify everything. Here are the updated entities that are working:
package com.zack.music.domain;
import javax.persistence.*;
import java.io.Serializable;
import java.sql.Date;
import java.util.*;
#Entity(name="COMPOSER")
public class Composer implements Serializable {
#Id
#Column(name="NAME", nullable = false)
private String name;
#Column(name="BIRTH", nullable = false)
private Date birth;
#Column(name="DEATH", nullable = true)
private Date death;
#ElementCollection
#CollectionTable(
name="COMPOSITION",
joinColumns=#JoinColumn(name="COMPOSER", referencedColumnName="NAME")
)
#Column(name="NAME")
private List<String> compositions;
protected Composer() { }
public Composer(String name, Date birth, Date death) {
this.name = name;
this.birth = birth;
this.death = death;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Date getDeath() {
return death;
}
public void setDeath(Date death) {
this.death = death;
}
public List<String> getCompositions() {
return compositions;
}
}
#Entity(name="COMPOSITION")
public class Composition implements Serializable {
#Id
#Column(name="NAME", nullable = false)
private String name;
#Column(name="COMPOSER", nullable = false)
private String composer;
protected Composition() { }
public Composition(String name, String composer) {
this.name = name;
this.composer = composer;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComposer() {
return composer;
}
public void setComposer(String composer) {
this.composer = composer;
}
}
I am quite interested in a Hibernate mapping such as the Order/Product/LineItem described here:
http://docs.jboss.org/hibernate/stable/core/reference/en/html/example-mappings.html#example-mappings-customerorderproduct
The documentation seems quite thorough, but I am a bit unclear on the semantics of the Java classes that one would create...
Any hints much appreciated.
Thank you!
Misha
Using that example, you would have classes that looked like the following:
import java.util.HashSet;
import java.util.Set;
public class Customer {
private String name = null;
private Set<Order> orders = new HashSet<Order>();
private long id = 0;
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 Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Order {
private long id = 0;
private Date date = null;
private Customer customer = null;
private List<LineItem> lineItems = new ArrayList<LineItem>();
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public List<LineItem> getLineItems() {
return lineItems;
}
public void setLineItems(List<LineItem> lineItems) {
this.lineItems = lineItems;
}
}
public class LineItem {
private int quantity = 0;
private Product product = null;
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
}
public class Product {
private long id = 0;
private String serialNumber = null;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getSerialNumber() {
return serialNumber;
}
public void setSerialNumber(String serialNumber) {
this.serialNumber = serialNumber;
}
}
If you create the tables as per the structure in the example, that should set you up.
They show the UML and the class members in the diagram.
A Customer can have zero to many Order objects (Set).
An Order has at least one to many LineItem objects. {List).
A LineItem entry corresponds to a Product. So LineItem has exactly one Product object.
Not sure what your question is?