Select key from jsonb postgreSQL using Hibernate Criteria query in Java - java

I am writing the criteria query to get results for jsonb in postgres.I can query the jsonb column through hibernate.I am unable to fetch jsonb specific keys.I am not able to find a way.
I have tried native query but i want some wayout in hibernate criteria query.The commonjson argument is the jsonb in postgresql is this --
{"appl_id": 726516, "applied_by": "pankajkumarnnl94#gmail.com", "service_id": 9880004, "version_no": 4, "appl_ref_no": "BSEH/2018/00728", "sub_version": 1, "payment_date": "2018-12-04T11:54:20.24+05:30", "payment_mode": "PayUbizz", "reference_no": "7726929249", "service_name": "Migration Certificate Board of School Education Haryana, Bhiwani", "department_id": 784, "location_value": 1218758, "base_service_id": 988, "department_name": " Board of School Education Haryana", "registration_id": "", "submission_date": "2018-12-04", "submission_mode": "online", "no_of_attachment": 2, "submission_location": "1578947~1218758~Board of School Education Haryana"}
Model Class ->ApplInfoJson
package com.saral.reporting.model;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Type;
import com.fasterxml.jackson.annotation.JsonProperty;
#Entity
#Table(name = "r_app_json",schema="saral1", catalog="saral1")
public class ApplInfoJson {
#Id
#Column(name = "aid")
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long aid;
#Column(name = "id")
private Long id;
#JsonProperty("appl_info")
#Column(name = "appl_info")
private String applInfo;
#Column(name = "application_form_attributes")
private String applicationFormAttributes;
#Column(name = "enclosure_data")
private String enclosureData;
#Column(name = "service_id")
private Long serviceId;
#Column(name = "combined_json")
#Type(type = "JsonDataUserType")
private Map<String , Object> combinedJson;
#Column(name ="location_value")
private Long locationValue;
public Long getLocationValue() {
return locationValue;
}
public void setLocationValue(Long locationValue) {
this.locationValue = locationValue;
}
public Long getServiceId() {
return serviceId;
}
public void setServiceId(Long serviceId) {
this.serviceId = serviceId;
}
public Long getAid() {
return aid;
}
public void setAid(Long aid) {
this.aid = aid;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getApplInfo() {
return applInfo;
}
public void setApplInfo(String applInfo) {
this.applInfo = applInfo;
}
public String getApplicationFormAttributes() {
return applicationFormAttributes;
}
public void setApplicationFormAttributes(String applicationFormAttributes) {
this.applicationFormAttributes = applicationFormAttributes;
}
public String getEnclosureData() {
return enclosureData;
}
public void setEnclosureData(String enclosureData) {
this.enclosureData = enclosureData;
}
public Map<String, Object> getCombinedJson() {
return combinedJson;
}
public void setCombinedJson(Map<String, Object> combinedJson) {
this.combinedJson = combinedJson;
}
#Override
public String toString() {
return "ApplInfoJson [aid=" + aid + ", id=" + id + ", applInfo=" + applInfo + ", applicationFormAttributes="
+ applicationFormAttributes + ", enclosureData=" + enclosureData + ", serviceId=" + serviceId
+ ", combinedJson=" + combinedJson + ", locationValue=" + locationValue + "]";
}
}
Function Used->
public List<ApplInfoJson> findByCombinedJson(String commonJson) {
DetachedCriteria criteria = DetachedCriteria.forClass(ApplInfoJson.class);
List<ApplInfoJson> results = (List<ApplInfoJson>) getHibernateTemplate().findByCriteria(criteria);
return results;
}
I want some thing to pass key name and get data with specific key.

Related

how to fetch all data from database using one to many relation hibernate query

I have two table Parent table is Credit in that table only one row of data is there and another one is child table Debit that contains multiple row of data. how to fetch data from two table which has to match id of parent class and child class and no duplicate is shown from parent class.
I have try with (from Credit,debit) but that can display with duplicate and not properly data is shown based on id.
package com.rojmat.entity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.springframework.core.annotation.Order;
#Entity
#Table(name="credit")
public class Credit extends BaseEntity{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private long cid;
#Column #Order
private long openingbalance;
#Column
private Date date;
#Column #Order
private long debittotal;
#Column #Order
private long drawertotal;
#Column #Order
private long debittotalplusdrawertotal;
#Column #Order
private long todaybusiness;
#OneToMany(cascade={CascadeType.ALL})
#JoinTable(name="credit_debit",
joinColumns=#JoinColumn(name="c_id"),
inverseJoinColumns=#JoinColumn(name="d_id"))
/*#JoinColumn(name="cid", referencedColumnName="cid")*/
private List<Debit> debits = new ArrayList<Debit>(Arrays.asList());
public Credit() {
}
public Credit(long cid, long openingbalance, Date date, long debittotal, long drawertotal,
long debittotalplusdrawertotal, long todaybusiness, List<Debit> debits) {
super();
this.cid = cid;
this.openingbalance = openingbalance;
this.date = date;
this.debittotal = debittotal;
this.drawertotal = drawertotal;
this.debittotalplusdrawertotal = debittotalplusdrawertotal;
this.todaybusiness = todaybusiness;
this.debits = debits;
}
public long getCid() {
return cid;
}
public void setCid(long cid) {
this.cid = cid;
}
public long getOpeningbalance() {
return openingbalance;
}
public void setOpeningbalance(long openingbalance) {
this.openingbalance = openingbalance;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public long getDebittotal() {
return debittotal;
}
public void setDebittotal(long debittotal) {
this.debittotal = debittotal;
}
public long getDrawertotal() {
return drawertotal;
}
public void setDrawertotal(long drawertotal) {
this.drawertotal = drawertotal;
}
public long getDebittotalplusdrawertotal() {
return debittotalplusdrawertotal;
}
public void setDebittotalplusdrawertotal(long debittotalplusdrawertotal) {
this.debittotalplusdrawertotal = debittotalplusdrawertotal;
}
public long getTodaybusiness() {
return todaybusiness;
}
public void setTodaybusiness(long todaybusiness) {
this.todaybusiness = todaybusiness;
}
public List<Debit> getDebit() {
return debits;
}
public void setDebit(List<Debit> debit) {
this.debits = debits;
}
/*#Override
public String toString() {
return "Credit [cid=" + cid + ", openingbalance =" + openingbalance + ", date=" + date + ", debittotal= " + debittotal + ", debittotalplusdrawertotal=" + debittotalplusdrawertotal + ", todaybusiness=" + todaybusiness + "]";
}*/
}
package com.rojmat.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="debit")
public class Debit {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private long did;
#Column
private String amount;
#Column
private String description;
public Debit() {
}
public Debit(String amount, String description) {
super();
this.amount = amount;
this.description = description;
}
public long getDid() {
return did;
}
public void setDid(long did) {
this.did = did;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public String toString() {
return "Debit [did=" + did + ", amount =" + amount + ", description=" + description + "]";
}
}
1.CreditDaoImpl.java
package com.rojmat.daoImpl;
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.rojmat.dao.CreditDao;
import com.rojmat.entity.Credit;
#Repository
public class CreditDaoImpl implements CreditDao{
#Autowired
private SessionFactory sessionFactory;
#Override
public void addCreditDebit(Credit credit) {
try {
sessionFactory.getCurrentSession().saveOrUpdate(credit);
} catch(Exception e) {
e.printStackTrace();
}
}
#Override
public void deleteCreditDebit(int cid) {
/*Credit credit = (Credit)sessionFactory.getCurrentSession().createQuery("from Credit as c LEFT JOIN FETCH c.Debit where c.cid="+cid).uniqueResult();
List<Debit> debits = credit.getDebit();
sessionFactory.getCurrentSession().delete(credit);
debits.forEach((debit) -> {
sessionFactory.getCurrentSession().delete(debit);
});*/
}
#SuppressWarnings("unchecked")
#Override
public List<Credit> getAllCreditDebit() {
List<Credit> credit = sessionFactory.getCurrentSession().createQuery("from Credit,Debit").list();
return credit;
}
}
try this example: you put "distinct" before the property you do not want to be duplicated
//SQL query
select distinct credit.idCredit as idCredit from Credit credit Left Join Debit debit on credit.idCredit= debit.idCredit
//HQL query
#Entity(name = "Credit")
#Table(name = "Credit")
public class Credit{
//if you put #Id --> HQL Query "select credit from Credit credit"
#Column(name = "idCredit")
private Long idCredit;
#Column(name = "label")
private String label;
#OneToMany
#JoinColumns({#JoinColumn(name = "idCredit" ,referencedColumnName = "idCredit")})
List<Debit> debits;
...
}
public class Debit{
....
#Column(name = "idCredit")
private Long idCredit;
...
}
Query query = getSession().createQuery("select distinct credit.idCredit as idCredit, credit.label as label, credit.debits as debits from Credit credit ");
query.setResultTransformer(Transformers.aliasToBean(Credit.class));
return query.list();
package com.rojmat.entity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.springframework.core.annotation.Order;
#Entity
#Table(name="credit")
public class Credit extends BaseEntity{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private long cid;
#Column #Order
private long openingbalance;
#Column
private Date date;
#Column #Order
private long debittotal;
#Column #Order
private long drawertotal;
#Column #Order
private long debittotalplusdrawertotal;
#Column #Order
private long todaybusiness;
#OneToMany(cascade={CascadeType.ALL})
#JoinTable(name="credit_debit",
joinColumns=#JoinColumn(name="c_id"),
inverseJoinColumns=#JoinColumn(name="d_id"))
/*#JoinColumn(name="cid", referencedColumnName="cid")*/
private List<Debit> debits = new ArrayList<Debit>(Arrays.asList());
public Credit() {
}
public Credit(long cid, long openingbalance, Date date, long debittotal, long drawertotal,
long debittotalplusdrawertotal, long todaybusiness, List<Debit> debits) {
super();
this.cid = cid;
this.openingbalance = openingbalance;
this.date = date;
this.debittotal = debittotal;
this.drawertotal = drawertotal;
this.debittotalplusdrawertotal = debittotalplusdrawertotal;
this.todaybusiness = todaybusiness;
this.debits = debits;
}
public long getCid() {
return cid;
}
public void setCid(long cid) {
this.cid = cid;
}
public long getOpeningbalance() {
return openingbalance;
}
public void setOpeningbalance(long openingbalance) {
this.openingbalance = openingbalance;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public long getDebittotal() {
return debittotal;
}
public void setDebittotal(long debittotal) {
this.debittotal = debittotal;
}
public long getDrawertotal() {
return drawertotal;
}
public void setDrawertotal(long drawertotal) {
this.drawertotal = drawertotal;
}
public long getDebittotalplusdrawertotal() {
return debittotalplusdrawertotal;
}
public void setDebittotalplusdrawertotal(long debittotalplusdrawertotal) {
this.debittotalplusdrawertotal = debittotalplusdrawertotal;
}
public long getTodaybusiness() {
return todaybusiness;
}
public void setTodaybusiness(long todaybusiness) {
this.todaybusiness = todaybusiness;
}
public List<Debit> getDebit() {
return debits;
}
public void setDebit(List<Debit> debit) {
this.debits = debits;
}
/*#Override
public String toString() {
return "Credit [cid=" + cid + ", openingbalance =" + openingbalance + ", date=" + date + ", debittotal= " + debittotal + ", debittotalplusdrawertotal=" + debittotalplusdrawertotal + ", todaybusiness=" + todaybusiness + "]";
}*/
}
package com.rojmat.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="debit")
public class Debit {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column
private long did;
#Column
private String amount;
#Column
private String description;
public Debit() {
}
public Debit(String amount, String description) {
super();
this.amount = amount;
this.description = description;
}
public long getDid() {
return did;
}
public void setDid(long did) {
this.did = did;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
/*#Override
public String toString() {
return "Debit [did=" + did + ", amount =" + amount + ", description=" + description + "]";
}*/
}

Hibernate error: found shared references

Request processing failed; nested exception is
org.springframework.orm.hibernate5.HibernateSystemException: Found
shared references to a collection:
sabeja.entity.ClassificatorObject.apartmentPayers; nested exception is
org.hibernate.HibernateException: Found shared references to a
collection: sabeja.entity.ClassificatorObject.apartmentPayers
I have been searching solution for 2 days. I found solutions in the stackoverflow, but they didn't help for me. I disabled parts of code, but I haven't caught problem.
ClassificatorObject Entity
package xm.entity;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
#Entity
#Table(name="managment_responsibilities_object")
public class ClassificatorObject implements Serializable{
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private int id;
#Column(name="responsibility_id")
private int responsibilityId;
#Column(name="object_id")
private int objectId;
#Column(name="is_enabled")
private int isEnabled;
#Column(name="by_area")
private int byArea;
#Column(name="by_people")
private int byPeople;
#Column(name="by_flat")
private int byFlat;
#Column(name="is_general")
private int isGeneral;
#Column(name="sort")
private int sort;
#Column(name="not_counting")
private int notCounting;
// #OneToMany(fetch = FetchType.LAZY, mappedBy = "classificatorObject", cascade = CascadeType.ALL)
// #OrderBy("month")
// private Set<ServicePeriod> periods;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name = "service_id", insertable=false, updatable=false)
private Set<ServiceOption> options;
#OneToMany(fetch = FetchType.LAZY)
//#JoinColumn(name = "service_id", insertable=false, updatable=false)
#JoinColumn(
name = "object_id",
referencedColumnName = "object_id",
insertable=false, updatable=false
)
private Set<ApartmentPayer> apartmentPayers;
public Set<ApartmentPayer> getApartmentPayers() {
return apartmentPayers;
}
public void setApartmentPayers(Set<ApartmentPayer> apartmentPayers) {
this.apartmentPayers = apartmentPayers;
}
#Column(name="parent_service_id")
private int parentServiceId;
#Column(name="has_children")
private int hasChildren;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name="responsibility_id", insertable=false, updatable=false)
private Classificator classificator;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name="parent_service_id", insertable=false, updatable=false)
private ClassificatorObject parentService;
//CONSTRUCTORS:
public ClassificatorObject() {
}
public ClassificatorObject(int responsibilityId, int objectId, int isEnabled, int byArea, int byPeople, int byFlat,
int isGeneral, int sort, int notCounting, Set<ServicePeriod> periods, Set<ServiceOption> options,
int parentServiceId, int hasChildren, Classificator classificator) {
super();
this.responsibilityId = responsibilityId;
this.objectId = objectId;
this.isEnabled = isEnabled;
this.byArea = byArea;
this.byPeople = byPeople;
this.byFlat = byFlat;
this.isGeneral = isGeneral;
this.sort = sort;
this.notCounting = notCounting;
// this.periods = periods;
this.options = options;
this.parentServiceId = parentServiceId;
this.hasChildren = hasChildren;
this.classificator = classificator;
}
//GETTERS SETTERS:
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getResponsibilityId() {
return responsibilityId;
}
public void setResponsibilityId(int responsibilityId) {
this.responsibilityId = responsibilityId;
}
public int getObjectId() {
return objectId;
}
public void setObjectId(int objectId) {
this.objectId = objectId;
}
public int getIsEnabled() {
return isEnabled;
}
public void setIsEnabled(int isEnabled) {
this.isEnabled = isEnabled;
}
public int getByArea() {
return byArea;
}
public void setByArea(int byArea) {
this.byArea = byArea;
}
public int getByPeople() {
return byPeople;
}
public void setByPeople(int byPeople) {
this.byPeople = byPeople;
}
public int getByFlat() {
return byFlat;
}
public void setByFlat(int byFlat) {
this.byFlat = byFlat;
}
public int getIsGeneral() {
return isGeneral;
}
public void setIsGeneral(int isGeneral) {
this.isGeneral = isGeneral;
}
public int getSort() {
return sort;
}
public void setSort(int sort) {
this.sort = sort;
}
public int getNotCounting() {
return notCounting;
}
public void setNotCounting(int notCounting) {
this.notCounting = notCounting;
}
// public Set<ServicePeriod> getPeriods() {
// return periods;
// }
//
// public void setPeriods(Set<ServicePeriod> periods) {
// this.periods = periods;
// }
public Set<ServiceOption> getOptions() {
return options;
}
public void setOptions(Set<ServiceOption> options) {
this.options = options;
}
public int getParentServiceId() {
return parentServiceId;
}
public void setParentServiceId(int parentServiceId) {
this.parentServiceId = parentServiceId;
}
public int getHasChildren() {
return hasChildren;
}
public void setHasChildren(int hasChildren) {
this.hasChildren = hasChildren;
}
public Classificator getClassificator() {
return classificator;
}
public void setClassificator(Classificator classificator) {
this.classificator = classificator;
}
public ClassificatorObject getParentService() {
return parentService;
}
public void setParentService(ClassificatorObject parentService) {
this.parentService = parentService;
}
#Override
public String toString() {
return "ClassificatorObject [id=" + id + ", responsibilityId=" + responsibilityId + ", objectId=" + objectId
+ ", isEnabled=" + isEnabled + ", byArea=" + byArea + ", byPeople=" + byPeople + ", byFlat=" + byFlat
+ ", isGeneral=" + isGeneral + ", sort=" + sort + ", notCounting=" + notCounting + ", parentServiceId="
+ parentServiceId + ", hasChildren=" + hasChildren + "]";
}
}
ApartmentPayer Entity
package sabeja.entity;
import java.math.BigDecimal;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
#Entity
#Table(name="sb_flat_payers")
public class ApartmentPayer {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private Integer id;
#Column(name="flat_id")
private int flatId;
#Column(name="payer_id")
private int payerId;
#Column(name="object_id")
private int objectId;
#Column(name="area", columnDefinition="Decimal(12,2)")
private BigDecimal area;
#Column(name="people_number")
private int peopleNumber;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name="flatPayer_id", insertable=false, updatable=false)
private Set<ServiceOption> options;
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name="payer_id", insertable= false, updatable= false)
private User user;
// #ManyToOne(fetch = FetchType.LAZY)
// #JoinColumn(name="object_id", insertable=false, updatable=false)
// private TheObject theObject;
public ApartmentPayer() {
super();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Set<ServiceOption> getOptions() {
return options;
}
public void setOptions(Set<ServiceOption> options) {
this.options = options;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public int getFlatId() {
return flatId;
}
public void setFlatId(int flatId) {
this.flatId = flatId;
}
public int getPayerId() {
return payerId;
}
public void setPayerId(int payerId) {
this.payerId = payerId;
}
public BigDecimal getArea() {
return area;
}
public void setArea(BigDecimal area) {
this.area = area;
}
public int getPeopleNumber() {
return peopleNumber;
}
public void setPeopleNumber(int peopleNumber) {
this.peopleNumber = peopleNumber;
}
public int getObjectId() {
return objectId;
}
public void setObjectId(int objectId) {
this.objectId = objectId;
}
// public TheObject getTheObject() {
// return theObject;
// }
//
//
//
// public void setTheObject(TheObject theObject) {
// this.theObject = theObject;
// }
#Override
public String toString() {
return "ApartmentPayer [id=" + id + ", flatId=" + flatId + ", payerId=" + payerId + ", area=" + area
+ ", peopleNumber=" + peopleNumber + "]";
}
}
DAOIMPL
Query<Apartment> queryResult2 = currentSession
.createQuery("SELECT DISTINCT a FROM Apartment a "
+ "JOIN FETCH a.theObject o "
+ "JOIN FETCH o.services s "
+ "JOIN FETCH s.apartmentPayers ap "
// + "LEFT JOIN FETCH s.options op "
// + "JOIN ServicePeriod p ON s.id = p.responsibilities_object_id "
// + "JOIN FETCH ap.user u "
+ "WHERE a.houseId = :object_id "
// + "AND (op.flatPayerId = ap.id OR op.id is NULL) "
//+ "AND (SELECT count(*) FROM DisabledPayer di WHERE di.serviceId = s.id AND di.flatPayerId = ap.id) = 0"
// + "AND (CASE WHEN op.is_disabled = 0 THEN 1 WHEN op.is_disabled = 1 "
// + "THEN 0 END) = 1) OR op.id IS NULL"
, Apartment.class);
This error can happen in some specific cases when you have kind of a 'loop' reference, but in this case you don't have a class with a field that uses this same class.
So the error has to be in a call to the method setApartmentPayers(), you need to check all the calls to the method and ensure that you are not assigning the same collection to two different entities.

Hibernate adding an extra sql statement

I am developing a restful ws that one of its methods is to insert some data in a database. The info is passed via Json, and at first I thought that maybe the json was incorrect, buy when I debug the app, the server side is correctly building the object that then i passed to hibernate saveOrUpdate(). This is what happens:
Hibernate: update CargasEnc set Fecha=?, HojaRutaID=?, CargaTipoID=? where CargaEncID=?
Hibernate: update CargasDet set Averiado=?, Cambio=?, Entrega=?, EnvaseID=?, Lleno=?, Retiro=?, Vacio=? where CargaDetID=?
Hibernate: update CargasDet set Averiado=?, Cambio=?, Entrega=?, EnvaseID=?, Lleno=?, Retiro=?, Vacio=? where CargaDetID=?
Hibernate: update CargasDet set Averiado=?, Cambio=?, Entrega=?, EnvaseID=?, Lleno=?, Retiro=?, Vacio=? where CargaDetID=?
Hibernate: update CargasDet set Averiado=?, Cambio=?, Entrega=?, EnvaseID=?, Lleno=?, Retiro=?, Vacio=? where CargaDetID=?
Hibernate: update CargasDet set Averiado=?, Cambio=?, Entrega=?, EnvaseID=?, Lleno=?, Retiro=?, Vacio=? where CargaDetID=?
Hibernate: update CargasDet set Averiado=?, Cambio=?, Entrega=?, EnvaseID=?, Lleno=?, Retiro=?, Vacio=? where CargaDetID=?
Hibernate: update CargasDet set CargaEncID=null where CargaEncID=?
That last line is strange, why is putting cargaEncId null and when i checked with log4j cargaEncId has a value of 1654.
Another thing I tried was to use a test client on the server. I got the same object from the database, changed some items, and the saveOrUpdate() and it worked, and hibernate did all the same sql statements than before except for the last one.
This are my two classes:
package com.designfreed.entities;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name = "CargasEnc")
public class Carga {
#Id
#GeneratedValue
#Column(name = "CargaEncID")
private Long id;
#Column(name = "Fecha")
private Date fecha;
#ManyToOne
#JoinColumn(name = "CargaTipoID")
private CargaTipo tipo;
#Column(name = "HojaRutaID")
private Long hojaRutaId;
#OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
#JoinColumn(name = "CargaEncID")
private List<ItemCarga> items;
public Carga() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getFecha() {
return fecha;
}
public void setFecha(Date fecha) {
this.fecha = fecha;
}
public CargaTipo getTipo() {
return tipo;
}
public void setTipo(CargaTipo tipo) {
this.tipo = tipo;
}
public Long getHojaRutaId() {
return hojaRutaId;
}
public void setHojaRutaId(Long hojaRutaId) {
this.hojaRutaId = hojaRutaId;
}
public List<ItemCarga> getItems() {
return items;
}
public void setItems(List<ItemCarga> items) {
this.items = items;
}
#Override
public String toString() {
return "Carga [id=" + id + ", fecha=" + fecha + ", tipo=" + tipo + ", hojaRutaId=" + hojaRutaId + ", items="
+ items + "]";
}
}
package com.designfreed.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "CargasDet")
public class ItemCarga {
#Id
#GeneratedValue
#Column(name = "CargaDetID")
private Long id;
#Column(name = "EnvaseID")
private Integer envaseId;
#Column(name = "Lleno")
private Integer lleno;
#Column(name = "Vacio")
private Integer vacio;
#Column(name = "Averiado")
private Integer averiado;
#Column(name = "Retiro")
private Integer retiro;
#Column(name = "Entrega")
private Integer entrega;
#Column(name = "Cambio")
private Integer cambio;
public ItemCarga() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getEnvaseId() {
return envaseId;
}
public void setEnvaseId(Integer envaseId) {
this.envaseId = envaseId;
}
public Integer getLleno() {
return lleno;
}
public void setLleno(Integer lleno) {
this.lleno = lleno;
}
public Integer getVacio() {
return vacio;
}
public void setVacio(Integer vacio) {
this.vacio = vacio;
}
public Integer getAveriado() {
return averiado;
}
public void setAveriado(Integer averiado) {
this.averiado = averiado;
}
public Integer getRetiro() {
return retiro;
}
public void setRetiro(Integer retiro) {
this.retiro = retiro;
}
public Integer getEntrega() {
return entrega;
}
public void setEntrega(Integer entrega) {
this.entrega = entrega;
}
public Integer getCambio() {
return cambio;
}
public void setCambio(Integer cambio) {
this.cambio = cambio;
}
#Override
public String toString() {
return "ItemCarga [id=" + id + ", envaseId=" + envaseId + ", lleno=" + lleno + ", vacio=" + vacio
+ ", averiado=" + averiado + ", retiro=" + retiro + ", entrega=" + entrega + ", cambio=" + cambio + "]";
}
}
Thanks very much for your help

How to use OneToMany and ManyToOne with two entities that result from named queries in JPA

I have this two clases:
package cu.jpa.entities.views;
import cu.jpa.entities.BaseEntity;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import java.util.List;
#Entity
#NamedQuery(
name="SubstanceDescriptionEntity.findAll",
query="select " +
" new cu.jpa.entities.views.SubstanceDescriptionEntity(S.id, S.substanceId) " +
"from " +
" SubstanceEntity S "
)
public class SubstanceDescriptionEntity extends BaseEntity {
private int id;
private String substanceId;
private List<PatternDescriptionEntity> patterns;
public SubstanceDescriptionEntity(int id, String substanceId){
this.id = id;
this.substanceId = substanceId;
}
public SubstanceDescriptionEntity(){
}
#Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSubstanceId() {
return substanceId;
}
public void setSubstanceId(String substanceId) {
this.substanceId = substanceId;
}
#OneToMany(mappedBy = "substance")
public List<PatternDescriptionEntity> getPatterns() {
return patterns;
}
public void setPatterns(List<PatternDescriptionEntity> patterns) {
this.patterns = patterns;
}
}
This is class 2:
package cu.jpa.entities.views;
import cu.jpa.entities.BaseEntity;
import javax.persistence.*;
#Entity
#NamedQuery(
name="PatternDescriptionEntity.findAll",
query="select " +
" new cu.jpa.entities.views.PatternDescriptionEntity(P.id, " +
" E.encounterId, " +
" P.patternId, " +
" E.substanceId) " +
"from " +
" PatternEntity P " +
" inner join " +
" P.encounterByEncounterId E " +
" where P.encounterId = E.id "
)
public class PatternDescriptionEntity extends BaseEntity {
private int id;
private String patternId;
private String encounterId;
private int substanceId;
private SubstanceDescriptionEntity substance;
public PatternDescriptionEntity(int id, String encounterId, String patternId, int substanceId){
this.id = id;
this.patternId = patternId;
this.encounterId = encounterId;
this.substanceId = substanceId;
}
public PatternDescriptionEntity(){
}
#Id
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPatternId() {
return patternId;
}
public void setPatternId(String patternId) {
this.patternId = patternId;
}
public String getEncounterId() {
return encounterId;
}
public void setEncounterId(String encounterId) {
this.encounterId = encounterId;
}
public int getSubstanceId() {
return substanceId;
}
public void setSubstanceId(int substanceId) {
this.substanceId = substanceId;
}
#ManyToOne
#JoinColumn(name = "substanceId", insertable = false, updatable = false, referencedColumnName = "substanceId")
public SubstanceDescriptionEntity getSubstance() {
return substance;
}
public void setSubstance(SubstanceDescriptionEntity substance) {
this.substance = substance;
}
}
Both classes are the result of a named query execution. I can get all the elements correctly using this:
#Override
public List<PatternDescriptionEntity> findAll(){
Query query = entityManager.createNamedQuery("PatternDescriptionEntity.findAll",PatternDescriptionEntity.class);
List<PatternDescriptionEntity> items = query.getResultList();
return items;
}
The problem is that I would like to get the reference to the SubstanceDescriptionEntity that corresponds to the PatternDescriptionEntity, according to the details I think I should have placed in #ManyToOne annotation. Both entities are the result of a named query, not of a table mapping. That is why I am having troubles. Because when I execute this test:
#Autowired
PatternDescriptionService service;
#Test
public void test_count_with_filters() throws Exception {
List<PatternDescriptionEntity> patterns = service.findAll();
}
I can see the patterns list with values, but each individual instance of the list has the property substance in null, which means the mapping have some sort of trouble, which I can quite figure it out.
So the question is:
I have these two JPA Entities (not mapped to database tables, but to to named queries result). How can I define the relations of ManyToOne and OneToMany?

could not resolve property Query Exception

I get following exception when I try to display data from EmergencyContact. SurveyData and EmergencyData are related by OneToMany. I'm able to persist the data but not able to retrieve it back.
I want to give a SurveyID as input and get back emergency contacts of that survey. I verified all my setter and getter methods and they look okay. I'm unable to trace where I made mistake. Any help is appreciated.
16:53:42,029 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) Caused by: org.hibernate.QueryException: could not resolve property: survey_id of: masonsurveyejb.businesslogic.EmergencyContact [SELECT emc FROM masonsurveyejb.businesslogic.EmergencyContact emc WHERE emc.survey_id = 11]
My query string looks like below. I receive survey_id variable value as an argument in this method.
"SELECT emc FROM EmergencyContact emc WHERE emc.survey_id = " + survey_id
Following are my EmergencyContact and SurveyData classes
package masonsurveyejb.businesslogic;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
#Entity
#Table(name = "EmergencyData")
public class EmergencyContact implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#SequenceGenerator(name = "EMERGENCY_SEQUENCE", sequenceName = "Survey_Seq", initialValue = 100, allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "EMERGENCY_SEQUENCE")
private Integer contactId;
#Column(name = "Name")
private String emName;
#Column(name = "Phone")
private String emPhone;
#Column(name = "Email")
private String emEmail;
#ManyToOne
#JoinColumn(name = "SurveyID")
private SurveyData surveyData;
public Integer getContactId() {
return contactId;
}
public void setContactId(Integer contactId) {
this.contactId = contactId;
}
public SurveyData getSurveyData() {
return surveyData;
}
public void setSurveyData(SurveyData surveyData) {
this.surveyData = surveyData;
}
public String getEmName() {
return emName;
}
public void setEmName(String emName) {
this.emName = emName;
}
public String getEmPhone() {
return emPhone;
}
public void setEmPhone(String emPhone) {
this.emPhone = emPhone;
}
public String getEmEmail() {
return emEmail;
}
public void setEmEmail(String emEmail) {
this.emEmail = emEmail;
}
}
///////////////////////////////////////////////////////////////////////////////
// #filename: Student.java
// #description: This file is the a simple class which is used as a model
// object for Student.
//
// Modification History
// Date Author Change Reason
// ==== ====== =============
// 2014-02-20 Santosh K Tadikonda Initial Creation
//
///////////////////////////////////////////////////////////////////////////////
package masonsurveyejb.businesslogic;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
#Entity
public class SurveyData {
#Id
#SequenceGenerator(name = "SURVEY_SEQUENCE", sequenceName = "Survey_Seq", initialValue = 100, allocationSize = 1)
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SURVEY_SEQUENCE")
#Column(name = "SurveyID")
private Integer survey_id;
private String firstname;
private String lastname;
private String address;
private String city;
private String state;
private String zipcode;
private String telephone;
private String email;
private String surveydate;
#Column(name = "Likes")
private String chklike;
#Column(name = "Know")
private String radioknow;
private String recommend;
private String raffle;
private String comments;
#OneToMany(mappedBy = "surveyData", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<EmergencyContact> emContacts;
public List<EmergencyContact> getEmContacts() {
return emContacts;
}
public void setEmContacts(List<EmergencyContact> emContacts) {
this.emContacts = emContacts;
}
public Integer getSurvey_id() {
return survey_id;
}
public void setSurvey_id(Integer survey_id) {
this.survey_id = survey_id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getSurveydate() {
return surveydate;
}
public void setSurveydate(String surveydate) {
this.surveydate = surveydate;
}
public String getChklike() {
return chklike;
}
public void setChklike(String chklike) {
this.chklike = chklike;
}
public String getRadioknow() {
return radioknow;
}
public void setRadioknow(String radioknow) {
this.radioknow = radioknow;
}
public String getRecommend() {
return recommend;
}
public void setRecommend(String recommend) {
this.recommend = recommend;
}
public String getRaffle() {
return raffle;
}
public void setRaffle(String raffle) {
this.raffle = raffle;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public String toString() {
String studentString;
studentString = getSurvey_id() + ";" +getFirstname() + ";" + getLastname() + ";"
+ getAddress() + ";" + getCity() + ";" + getState() + ";"
+ getZipcode() + ";" + getTelephone() + ";" + getEmail() + ";"
+ getSurveydate() + ";" + getChklike() + ";" + getRadioknow()
+ ";" + getRecommend() + ";" + getRaffle() + ";"
+ getComments();
return studentString;
}
}
Following is the method from which I make query
#Override
public ArrayList<EmergencyContact> GetEmergencyContacts(String survey_id) {
try {
if (survey_id == null || survey_id.length() == 0) {
System.out.println("Received a null or empty survey ID.");
return null;
}
System.out.println("Getting emergency contacts for " + survey_id);
String queryStr = "SELECT emc FROM EmergencyContact emc WHERE emc.survey_id = "
+ survey_id;
Query query = entityManager.createQuery(queryStr);
List resultList = query.getResultList();
if (resultList != null && resultList.size() > 0) {
ArrayList<EmergencyContact> emList = new ArrayList<EmergencyContact>();
for (Object result : resultList) {
EmergencyContact emc = new EmergencyContact();
emc = (EmergencyContact) result;
emList.add(emc);
}
return emList;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
You receiving the exception because entity 'EmergencyContact' has no property named 'survey_id'.
Your query should be:
String queryStr = "SELECT emc FROM EmergencyContact emc WHERE emc.surveyData.survey_id = :id";
Query query = entityManager.createQuery(queryStr).setParameter("id", survey_id);
List resultList = query.getResultList();
Please consider 2 things:
Use property names in JPQL query (surveyData.survey_id)
It's better to set query parameters with special method, "setParameter"

Categories