Select from with boolean functions - java

I am trying to develop an application with Java EE. Here is a part of my class diagram which I want to to implement:
Here is the implementation of classes with hibernate:
#Entity
#Table(name = "t_enseignant")
public class Enseignant extends User implements Serializable {
private static final long serialVersionUID = 1L;
private String specialite;
private List<Module> modules;
public Enseignant() {
}
public Enseignant(String nom, String prenom, String email, String login, String password, String specialite) {
super(nom, prenom, email, login, password);
this.setSpecialite(specialite);
}
public String getSpecialite() {
return specialite;
}
public void setSpecialite(String specialite) {
this.specialite = specialite;
}
#OneToMany(mappedBy = "enseignant")
public List<Module> getModules() {
return modules;
}
public void setModules(List<Module> modules) {
this.modules = modules;
}
}
#Entity
#Table(name = "t_classe")
public class Classe implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String niveau;
private int nbreEtudiant;
private List<Module> modules;
public Classe() {
}
public Classe(String niveau, int nbreEtudiant) {
this.niveau = niveau;
this.nbreEtudiant = nbreEtudiant;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() {
return id;
}
...
I also implemented the Module Class and ModulePK.
I want to check that a teacher should be assigned to a class once.
I tried with the following JPQL query
boolean exists = false;
String jpql = "select case when (count(m) > 0) then true else false end from Module m where m.idEnseignant=idEnseignant and m.idClasse=idClasse";
TypedQuery<Boolean> query = entityManager.createQuery(jpql, Boolean.class);
query.setParameter("idEnseignant", enseignant.getId());
query.setParameter("idClasse", classeToValidate.getId());
exists = query.getSingleResult();
but when I execute the method I have this exception
could not resolve property: idEnseignant of: domain.Module [select case when (count(m) > 0) then true else false end from domain.Module m where m.idEnseignant=idEnseignant and m.idClasse=idClasse]

You forgot to the : to indicate your named parameters, so you had idEnseignant=idEnseignant instead of idEnseignant=:idEnseignant
Here's the corrected code:
boolean exists = false;
String jpql = "select case when (count(m) > 0) then true else false end from Module m where m.idEnseignant=:idEnseignant and m.idClasse=:idClasse";
TypedQuery<Boolean> query = entityManager.createQuery(jpql, Boolean.class);
query.setParameter("idEnseignant", enseignant.getId());
query.setParameter("idClasse", classeToValidate.getId());
exists = query.getSingleResult();
return exists

In your Module entity you define modulePk to be the primary key. There are two possiblities to use this id:
Create an instance of ModulePk class and pass it to the find() method of the entity manager (which is not the case in your query), or
To use it in JPQL query you have to traverse the embedded id class. In your case use it as follows:
String jpql = "select case when (count(m) > 0) then true else false end from Module m where m.modulePk.idEnseignant = :idEnseignant and m.modulePk.idClasse = :idClasse";

#jens
#Entity
#Table(name = "t_module")
public class Module implements Serializable {
private static final long serialVersionUID = 1L;
private ModulePk modulePk;
private String nomModule;
private int nbreHeure;
private Enseignant enseignant;
private Classe classe;
public Module() {
}
public Module(String nomModule, int nbreHeure, Enseignant enseignant, Classe classe) {
this.nomModule = nomModule;
this.nbreHeure = nbreHeure;
this.enseignant = enseignant;
this.classe = classe;
this.modulePk = new ModulePk(enseignant.getId(), classe.getId());
}
#EmbeddedId
public ModulePk getModulePk() {
return modulePk;
}
public void setModulePk(ModulePk modulePk) {
this.modulePk = modulePk;
}
public String getNomModule() {
return nomModule;
}
public void setNomModule(String nomModule) {
this.nomModule = nomModule;
}
public int getNbreHeure() {
return nbreHeure;
}
public void setNbreHeure(int nbreHeure) {
this.nbreHeure = nbreHeure;
}
#ManyToOne
#JoinColumn(name = "idEnseignant", referencedColumnName = "id", insertable = false, updatable = false)
public Enseignant getEnseignant() {
return enseignant;
}
public void setEnseignant(Enseignant enseignant) {
this.enseignant = enseignant;
}
#ManyToOne
#JoinColumn(name = "idClasse", referencedColumnName = "id", insertable = false, updatable = false)
public Classe getClasse() {
return classe;
}
public void setClasse(Classe classe) {
this.classe = classe;
}
}
and this is ModulePK class
#Embeddable
public class ModulePk implements Serializable {
private static final long serialVersionUID = 1L;
private int idEnseignant;
private int idClasse;
public ModulePk() {
}
public ModulePk(int idEnseignant, int idClasse) {
this.setIdEnseignant(idEnseignant);
this.setIdClasse(idClasse);
}
...

Related

could not serialize; nested exception is org.hibernate.type.SerializationException: could not serialize

I have spend way too much find finding the root cause of the below error:
org.springframework.orm.jpa.JpaSystemException: could not serialize; nested exception is org.hibernate.type.SerializationException: could not serialize
I am trying to save some value to db:
public void logFailure(Long objectID,Integer usLK){
StatusFailureDO failureDO = new StatusFailureDO(4,objectID, usLK);
failuresRepository.save(failureDO.getFailure());
}
#Repository
public interface FailuresRepository extends JpaRepository<GeneralFailure, Integer> {
GeneralFailure save(GeneralFailure aGeneralFailure);
void delete(GeneralFailure aGeneralFailure);
GeneralFailure findByObjectID(Long objectID);
}
There were many mapping errors and as such that I got pass now. I am trying to understand where in the process error occurs and what shall I look out for.
public class StatusFailureDO extends GeneralFailureDO implements Serializable
{
public StatusFailureDO(Integer failureTypeLK,Long objectID,
Integer usLK)
{
super(new StatusFailure(failureTypeLK,
"An exception occurred while trying to update an UploadStatus entry.",
objectID, usLK));
}
//more constructors and setters
}
public abstract class GeneralFailureDO implements ICISConstant, Serializable
{
private GeneralFailure mGeneralFailure;
//constructors and setters
}
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "GEN_FLR")
public class GeneralFailure implements Serializable,ICISConstant
{
#Column(name = "CRTN_TM")
private Date mCreationTime;
#Column(name = "TYP_LKP_ID")
private Integer failureTypeLK;
#Column(name = "STUS_LKP_ID")
private Integer mFailureStatusLK;
#Column(name="OBJ_ID")
#Id
#GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
#GenericGenerator(name = "native", strategy = "native")
private Long objectID;
#Column(name = "DSCR")
private String mDescription;
public Date getCreationTime()
{
return mCreationTime;
}
public void setCreationTime(Date aCreationTime)
{
mCreationTime = aCreationTime;
}
public String getDescription()
{
return mDescription;
}
public void setDescription(String aDescription)
{
if (aDescription != null && aDescription.length() > MAX_DESCRIPTION_LENGTH)
{
mDescription = aDescription.substring(0, MAX_DESCRIPTION_LENGTH);
}
else
{
mDescription = aDescription;
}
}
public Long getObjectID()
{
return objectID;
}
public void setObjectID(Long aObjectID)
{
objectID = aObjectID;
}
public Integer getFailureTypeLK()
{
return failureTypeLK;
}
public void setFailureTypeLK(Integer aFailureTypeLK)
{
failureTypeLK = aFailureTypeLK;
}
public Integer getFailureStatusLK()
{
return mFailureStatusLK;
}
public void setFailureStatusLK(Integer aFailureStatusLK)
{
mFailureStatusLK = aFailureStatusLK;
}
}
#Entity
#Table(name="STUS_FLR")
public class StatusFailure extends GeneralFailure implements Serializable
{
#Column(name = "STUS_OBJ_ID")
private Long mStatusObjectID;
#Column(name = "STUS_LKP_ID")
private Integer mStatusLK;
#Column(name = "RQST_TYP_LKP_ID")
private Integer mRequestTypeLK;
#Column(name = "CODE")
private String mCode;
#Column(name = "PST_TM")
private Timestamp mPostTime;
#Column(name = "MSG_SZ")
private Integer mMessageSize;
#OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Collection<StatusFailureError> StatusFailureErrorList;
#Column(name = "SMPL_FLG")
private boolean mSimple;
public Integer getStatusLK()
{
return mStatusLK;
}
public void setStatusLK(Integer statusLK)
{
mStatusLK = statusLK;
}
public Long getStatusObjectID()
{
return mStatusObjectID;
}
public void setStatusObjectID(Long statusObjectID)
{
mStatusObjectID = statusObjectID;
}
public String getCode()
{
return mCode;
}
public void setCode(String aCode)
{
mCode = aCode;
}
public Collection<StatusFailureError> getStatusFailureErrorList()
{
return mStatusFailureErrorList;
}
public void setStatusFailureErrorList(
Collection<StatusFailureError> aStatusFailureErrorList)
{
mStatusFailureErrorList = aStatusFailureErrorList;
}
public void setErrorList(Collection<String> aErrorList)
{
if (aErrorList != null && !aErrorList.isEmpty())
{
mStatusFailureErrorList = new ArrayList<StatusFailureError>();
for (Iterator<String> iter = aErrorList.iterator(); iter.hasNext();)
{
String error = (String) iter.next();
StatusFailureError failureError = new StatusFailureError(this, error, getPostTime());
mStatusFailureErrorList.add(failureError);
}
}
else
{
mStatusFailureErrorList = null;
}
}
public Integer getMessageSize()
{
return mMessageSize;
}
public void setMessageSize(Integer aMessageSize)
{
mMessageSize = aMessageSize;
}
public Timestamp getPostTime()
{
return mPostTime;
}
public void setPostTime(Timestamp aPostTime)
{
mPostTime = aPostTime;
}
public Integer getRequestTypeLK()
{
return mRequestTypeLK;
}
public void setRequestTypeLK(Integer aRequestTypeLK)
{
mRequestTypeLK = aRequestTypeLK;
}
public boolean isSimple()
{
return mSimple;
}
public void setSimple(boolean aSimple)
{
mSimple = aSimple;
}
}
Any help is really appreciated.
It is not obvious what the failureDO.getFailure() returns exactly because you did not provide a method definition for the StatusFailureDO.getFailure() method and so I will assume that that method returns an instance of a GeneralFailure class (or StatusFailure that extends it).
For hibernate to successfully save objects into the database, the #Entity classes that you are trying to save need to consist of "base" types. I see that you have an object of class CLRISCache defined in your GeneralFailure data class, that is most definitely not of a base type and not another #Entity. You can prevent a field from being persisted by marking it with the #Transient annotation, but really you should keep your data class pure.
You can find a list of "base" types here: https://docs.jboss.org/hibernate/orm/5.0/mappingGuide/en-US/html/ch03.html
Actually I found the reason. The General failure has dateCreation variable of Date type and in mu status failure I had it as a timestamp. I need to make it to Date and it worked.

Hibernate: How to join a table with a column which is not a foreign key

I'm trying to create a OneToOne relation between tartikel and teigenschaft with the primary key kArtikel in tartikel. The code snippet in TArtikelEntity:
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "kArtikel", referencedColumnName="kArtikel")
public TeigenschaftEntity getTeigenschaftEntity() {
return teigenschaftEntity;
}
public void setTeigenschaftEntity(TeigenschaftEntity teigenschaftEntity) {
this.teigenschaftEntity = teigenschaftEntity;
}
The complete entity of teigenschaft:
#Entity
#Table(name = "teigenschaft", schema = "dbo", catalog = "Mandant_EinsZwei")
public class TeigenschaftEntity {
private int kEigenschaft;
private int kArtikel;
private String cWaehlbar;
private Integer nSort;
private String cTyp;
private String cAktiv;
#Id
#Column(name = "kEigenschaft")
public int getkEigenschaft() {
return kEigenschaft;
}
public void setkEigenschaft(int kEigenschaft) {
this.kEigenschaft = kEigenschaft;
}
#Basic
#Column(name = "kArtikel")
public int getkArtikel() {
return kArtikel;
}
public void setkArtikel(int kArtikel) {
this.kArtikel = kArtikel;
}
#Basic
#Column(name = "cWaehlbar")
public String getcWaehlbar() {
return cWaehlbar;
}
public void setcWaehlbar(String cWaehlbar) {
this.cWaehlbar = cWaehlbar;
}
#Basic
#Column(name = "nSort")
public Integer getnSort() {
return nSort;
}
public void setnSort(Integer nSort) {
this.nSort = nSort;
}
#Basic
#Column(name = "cTyp")
public String getcTyp() {
return cTyp;
}
public void setcTyp(String cTyp) {
this.cTyp = cTyp;
}
#Basic
#Column(name = "cAktiv")
public String getcAktiv() {
return cAktiv;
}
public void setcAktiv(String cAktiv) {
this.cAktiv = cAktiv;
}
}
Here is where I'm getting the NullPointerException (Line 4):
session.beginTransaction();
TArtikelEntity tArtikelEntity = session.get(TArtikelEntity.class, 189820);
System.out.println(tArtikelEntity.toString());
System.out.println(tArtikelEntity.getTeigenschaftEntity().getkEigenschaft()+" <---- kEigenschaft");
session.getTransaction().commit();
I located the problem in the second query. It's not using kArtikel but kEigenschaft (the primary key of teigenschaft):
select teigenscha0_.kEigenschaft as kEigensc1_12_0_, teigenscha0_.cAktiv as cAktiv2_12_0_, teigenscha0_.cTyp as cTyp3_12_0_, teigenscha0_.cWaehlbar as cWaehlba4_12_0_, teigenscha0_.kArtikel as kArtikel5_12_0_, teigenscha0_.nSort as nSort6_12_0_ from Mandant_EinsZwei.dbo.teigenschaft teigenscha0_ where teigenscha0_.kEigenschaft=?|select teigenscha0_.kEigenschaft as kEigensc1_12_0_, teigenscha0_.cAktiv as cAktiv2_12_0_, teigenscha0_.cTyp as cTyp3_12_0_, teigenscha0_.cWaehlbar as cWaehlba4_12_0_, teigenscha0_.kArtikel as kArtikel5_12_0_, teigenscha0_.nSort as nSort6_12_0_ from Mandant_EinsZwei.dbo.teigenschaft teigenscha0_ where teigenscha0_.kEigenschaft=189820
But how can that be? I mentioned the JoinColumn in TArtikelEntity to kArtikel. Why is it not using kArtikel but kEigenschaft?
Null pointer exception isn't due to join. It's because you are converting a null object to string.
try this :
System.out.println(tArtikelEntity==null?null:tArtikelEntity.toString());

Spring Data JPA - Get the values of a non-entity column of a custom native query

I am using Spring Boot/MVC.
I have a custom query using JpaRepository:
public interface WorkOrderRepository extends JpaRepository<WorkOrder, Integer> {
#Query(value = "SELECT * FROM (SELECT * FROM workorder) Sub1 INNER JOIN (SELECT wo_number, GROUP_CONCAT(service_type SEPARATOR ', ') AS 'service_types' FROM service_type GROUP BY wo_number) Sub2 ON Sub1.wo_number=Sub2.wo_number WHERE fleet_company_id=?1 AND (order_status='On-Bidding' OR order_status='Draft')", nativeQuery = true)
Collection<WorkOrder> findWorkOrdersByFleet(Long fleetCompanyID);
}
It returns the following table:
http://imgur.com/Ylkc6U0
As you can see it has service_types columns which is a result of Concat, it's not part of the entity class. My problem is how can I get the value of that column. Some said I can use a separate DTO to map the service_types column? Or I can use 'new' keyword? Maybe you have other worked on me. I also tried to make a transient column service_types but it didn't work.
This is my entity class:
#Entity
#Table(name="workorder")
public class WorkOrder {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="wo_number")
private Long woNumber;
#ManyToOne(optional=false, cascade=CascadeType.ALL)
#JoinColumn(name = "vehicle_id")
private Vehicle vehicle;
#ManyToOne(optional=false, cascade=CascadeType.ALL)
#JoinColumn(name = "fleet_company_id")
private FleetCompany fleetCompany;
#Column(name="order_title")
private String orderTitle;
#Column(name="order_date")
private String orderDate;
#Column(name="order_time")
private String orderTime;
#Column(name="order_status")
private String orderStatus;
#Column(name="ref_number")
private String refNumber;
#Column(name="proposals")
private int proposals;
//#Column(name="serviceTypes")
#Transient
private int serviceTypes;
public WorkOrder() {
super();
}
public Long getWoNumber() {
return woNumber;
}
public void setWoNumber(Long woNumber) {
this.woNumber = woNumber;
}
public String getOrderTitle() {
return orderTitle;
}
public void setOrderTitle(String orderTitle) {
this.orderTitle = orderTitle;
}
public String getOrderDate() {
return orderDate;
}
public void setOrderDate(String orderDate) {
this.orderDate = orderDate;
}
public String getOrderTime() {
return orderTime;
}
public void setOrderTime(String orderTime) {
this.orderTime = orderTime;
}
public String getOrderStatus() {
return orderStatus;
}
public void setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
}
public String getRefNumber() {
return refNumber;
}
public void setRefNumber(String refNumber) {
this.refNumber = refNumber;
}
public int getProposals() {
return proposals;
}
public void setProposals(int proposals) {
this.proposals = proposals;
}
public Vehicle getVehicle() {
return vehicle;
}
public void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}
public FleetCompany getFleetCompany() {
return fleetCompany;
}
public void setFleetCompany(FleetCompany fleetCompany) {
this.fleetCompany = fleetCompany;
}
public int getServiceTypes() {
return serviceTypes;
}
public void setServiceTypes(int serviceTypes) {
this.serviceTypes = serviceTypes;
}
}
Some people told me to make a DTO:
public class WorkOrderDTO extends WorkOrder {
private String service_types;
public WorkOrderDTO() {
super();
}
public WorkOrderDTO(String service_types) {
this.service_types = service_types;
}
public String getService_types() {
return service_types;
}
public void setService_types(String service_types) {
this.service_types = service_types;
}
}
and add make the repository replaced from WorkOrder to WorkOrderDTO.
public interface WorkOrderRepository extends JpaRepository<WorkOrderDTO, Integer>
but when I do that I have autowiring problems.
I solved my own problem, finally!!!
I used #SqlResultMapping
SqlResultSetMapping(
name="workorder",
classes={
#ConstructorResult(
targetClass=WorkOrderDTO.class,
columns={
#ColumnResult(name="wo_number", type = Long.class),
#ColumnResult(name="service_types", type = String.class),
#ColumnResult(name="order_title", type = String.class)
}
)
}
)
And I created a new POJO that is not an entity named WorkOrderDTO.
#PersistenceContext
private EntityManager em;
#Override
public Collection<WorkOrderDTO> getWork() {
Query query = em.createNativeQuery(
"SELECT Sub1.wo_number, Sub2.service_types, Sub1.order_title FROM (SELECT * FROM workorder) Sub1 INNER JOIN (SELECT wo_number, GROUP_CONCAT(service_type SEPARATOR ', ') AS 'service_types' FROM service_type GROUP BY wo_number) Sub2 ON Sub1.wo_number=Sub2.wo_number WHERE fleet_company_id=4 AND (order_status='On-Bidding' OR order_status='Draft')", "workorder");
#SuppressWarnings("unchecked")
Collection<WorkOrderDTO> dto = query.getResultList();
Iterable<WorkOrderDTO> itr = dto;
return (Collection<WorkOrderDTO>)itr;
}
At last, the users who hated me for posting the same problem won't be annoyed anymore.

Spring + hibernate : Expected type: java.util.SortedSet, actual value: org.hibernate.collection.internal.PersistentSet

I have a Client.class which has a OneToMany relation with Posto.class.
#Entity
#Table(name = "client", catalog = "SMARTPARK")
public class Client implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int idClient;
private String nomeClient;
private int numPosti;
private int numLuci;
private String currentIp;
private boolean online;
private String prop;
private SortedSet<Posto> posti = new TreeSet<>();
private SortedSet<Luce> luci = new TreeSet<>();
public Client() {
}
public Client(int idClient, String nomeClient, int numPosti, int numLuci,
String currentIp, boolean online, String prop,
SortedSet<Posto> posti, SortedSet<Luce> luci) {
this.idClient = idClient;
this.nomeClient = nomeClient;
this.numPosti = numPosti;
this.numLuci = numLuci;
this.currentIp = currentIp;
this.prop = prop;
this.online = online;
this.posti = posti;
this.luci = luci;
}
#Id
#Column(name = "id_client", unique = true, nullable = false)
public int getIdClient() {
return this.idClient;
}
public void setIdClient(int idClient) {
this.idClient = idClient;
}
#Column(name = "nome_client", nullable = false, length = 65535)
public String getNomeClient() {
return this.nomeClient;
}
public void setNomeClient(String nomeClient) {
this.nomeClient = nomeClient;
}
#Transient
public int getNumPosti() {
return this.numPosti;
}
public void setNumPosti(int numPosti) {
this.numPosti = numPosti;
}
#Transient
public int getNumLuci() {
return this.numLuci;
}
public void setNumLuci(int numLuci) {
this.numLuci = numLuci;
}
#Column(name = "client_ip", nullable=true)
public String getCurrentIp() {
return currentIp;
}
public void setCurrentIp(String currentIp) {
this.currentIp = currentIp;
}
#Column(name="online")
public boolean isOnline() {
return online;
}
public void setOnline(boolean online) {
this.online = online;
}
#Column(name="prop")
public String getProp() {
return prop;
}
public void setProp(String prop) {
this.prop = prop;
}
#OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy = "client", orphanRemoval=true)
#OrderBy("numeroPosto ASC")
public Set<Posto> getPosti() {
return posti;
}
public void setPosti(SortedSet<Posto> posti) {
this.posti = posti;
}
#OneToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL, mappedBy = "client", orphanRemoval=true)
#OrderBy("numeroLuce ASC")
public SortedSet<Luce> getLuci() {
return luci;
}
public void setLuci(SortedSet<Luce> luci) {
this.luci = luci;
}
This was made because a use the Set in a responseEntity Controller and I need to preserve the order of how postiis displayed in the Json output.
So in Posto.class I implemented Comparable interface, overrding the compareTo method
#Override
public int compareTo(Posto o) {
if(this.numeroPosto == o.numeroPosto){
return 0;
} else {
return this.numeroPosto > o.numeroPosto ? 1 : -1;
}
Now, when calling my controller, i got this error from Hibernate:
2016-03-30 16:18:07.486 ERROR [http-nio-8080-exec-6]: HHH000123: IllegalArgumentException in class: it.besmart.models.Client, setter method of property: posti
2016-03-30 16:18:07.486 ERROR [http-nio-8080-exec-6]: HHH000091: Expected type: java.util.SortedSet, actual value: org.hibernate.collection.internal.PersistentSet
How can i solve it? Hibernate changes my SortedSet in a PersistentSet, do I have to use this one to set my posti with the order i want?
The problem is you defined your posti and Luci as concrete SortSet. Hibernate PersistentSet implements generic Set interface. All you need to do is changing SortSet to generic Set and modify getters, setters accordingly.
private Set<Posto> posti;
private Set<Luce> luci;

Hibernate query using joins and like operator

I have two model classes:
Class 1 looks like this:
#Entity
#Table(name = "cdm_location_charge_class", catalog = "emscribedx")
public class Cdm_location_charge_class {
private static Logger LOG = Logger.getLogger(Cdm_location_charge_class.class);
private int indx;
private String location;
private String charge_Class;
private List <Cdm_trans> cdm_Trans;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "indx")
public int getIndx() {
return indx;
}
public void setIndx(int indx) {
this.indx = indx;
}
#Column(name = "location")
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
#Column(name = "charge_Class")
public String getCharge_Class() {
return charge_Class;
}
public void setCharge_Class(String charge_Class) {
this.charge_Class = charge_Class;
}
#OneToMany (mappedBy = "cdm_location_charge_class", targetEntity = Cdm_trans.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
public List<Cdm_trans> getCdm_Trans() {
return cdm_Trans;
}
public void setCdm_Trans(List<Cdm_trans> cdm_Trans) {
this.cdm_Trans = cdm_Trans;
}
And class 2 looks like this:
#Entity
#Table(name = "cdm_Trans", catalog = "emscribedx")
public class Cdm_trans {
private static Logger LOG = Logger.getLogger(Cdm_trans.class);
private int indx;
private String charge_Class;
private String charge_Code;
private String charge_Description;
private String charge_Eligibility;
private String exp_Date;
private BigDecimal rate_Charge;
private String cpt_Code;
private int rev_Code;
private String charge_Type;
private Cdm_location_charge_class cdm_location_charge_class;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "indx")
public int getIndx() {
return indx;
}
public void setIndx(int indx) {
this.indx = indx;
}
#Column(name = "charge_Class")
public String getCharge_Class() {
return charge_Class;
}
public void setCharge_Class(String charge_Class) {
this.charge_Class = charge_Class;
}
#Column(name = "charge_Code")
public String getCharge_Code() {
return charge_Code;
}
public void setCharge_Code(String charge_Code) {
this.charge_Code = charge_Code;
}
#Column(name = "charge_Description")
public String getCharge_Description() {
return charge_Description;
}
public void setCharge_Description(String charge_Description) {
this.charge_Description = charge_Description;
}
#Column(name = "charge_Eligibility")
public String getCharge_Eligibility() {
return charge_Eligibility;
}
public void setCharge_Eligibility(String charge_Eligibility) {
this.charge_Eligibility = charge_Eligibility;
}
#Column(name = "exp_Date")
public String getExp_Date() {
return exp_Date;
}
public void setExp_Date(String exp_Date) {
this.exp_Date = exp_Date;
}
#Column(name = "rate_Charge")
public BigDecimal getRate_Charge() {
return rate_Charge;
}
public void setRate_Charge(BigDecimal rate_Charge) {
this.rate_Charge = rate_Charge;
}
#Column(name = "cpt_Code")
public String getCpt_Code() {
return cpt_Code;
}
public void setCpt_Code(String cpt_Code) {
this.cpt_Code = cpt_Code;
}
#Column(name = "rev_Code")
public int getRev_Code() {
return rev_Code;
}
public void setRev_Code(int rev_Code) {
this.rev_Code = rev_Code;
}
#Column(name = "charge_Type")
public String getCharge_Type() {
return charge_Type;
}
public void setCharge_Type(String charge_Type) {
this.charge_Type = charge_Type;
}
#ManyToOne
#JoinColumn(name = "charge_Class", insertable = false, updatable = false)
public Cdm_location_charge_class getCdm_location_charge_class() {
return cdm_location_charge_class;
}
public void setCdm_location_charge_class(
Cdm_location_charge_class cdm_location_charge_class) {
this.cdm_location_charge_class = cdm_location_charge_class;
}
}
The two classes correspond to two underlying tables:
Cdm_trans and Cdm_location_charge_class.
I want to create a Hibernate Service that will give me the same result as the following sql query:
select cdm_trans.* from Cdm_trans, Cdm_location_charge_class where
cdm_location_charge_class.charge_Class = cdm_trans.charge_Class and
cdm_location_charge_class.location = <Some location passed to the method> and
Cdm_trans.charge_Description like '%<Some search term passed into the method>%;
My preference would be to do this using the Hibernate criteria API. But I will go with HQL if that is the only way. Can someone show me how to do this?
I've tried this HQL query:
Query query = session.createQuery("FROM cdm_location_charge_class as cl INNER JOIN cl.cdm_Trans where cl.location = :location and cdm_Trans.charge_Description like :search");
But I I get an error:
cdm_location_charge_class is not mapped
If you want to use Criteria, you just add a restriction.
List cats = session.createCriteria(Cat.class)
.createCriteria("kittens")
.add( Restrictions.like("name", "Iz%") )
.list();
HQL example:
Query query = session.createQuery("FROM Cdm_location_charge_class cl " +
"INNER JOIN cl.cdm_Trans trans " +
"where cl.location = :location and trans.charge_Description like :search")
.setParameter("location", locationValue)
.setParameter("search", "%" + searchValue + "%");
Can you be more specific about the issue, or are you just asking for a very specific tutorial?
Anyway why is HQL second choice. IMHO the Criteria Helper should only be used when constructing dynamic queries (add conditions based on user input for example). If you have a static query i would suggest HQL. It is also supposed to be faster. Also look into NamedQuery.
Here is the documentation on Criteria queries in Hibernate:
http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/querycriteria.html
Specifically, you want to look at the Restrictions class (http://docs.jboss.org/hibernate/orm/3.3/api/org/hibernate/criterion/Restrictions.html) and static methods like() and ilike(), where the latter handles case-insensitive comparison. I also tend towards HQL for static queries, but I have seen benefit at times to make static elements configurable, especially for debugging. Therefore, I may use the dynamic query approach with the query stored in a configuration file, so I can alter it easily for testing even though the application runs the same query typically.
Respectfully yours,
Kevin

Categories