I have a problem with hibernate HQL queries and simple INNER JOIN
String hql = "SELECT NEW es.criteria.crc.model.queryObjects.NameQuery(pf.name) FROM Person as p INNER JOIN PhisicalPerson as pf WHERE pf.idPersona = p.idPersona";
return personService.query(hql);
My Java file has the following code:
public class NameQuery{
private String name;
public NameQuery(String name) {
super();
this.name= name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
}
I recieve the following error in console:
Caused By: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join!
You need to have an association (#OneToMany, #OneToOne) between Person and PhisicalPerson. Having such an association you don't need the where clause
SELECT NEW es.criteria.crc.model.queryObjects.NameQuery(pf.name)
FROM Person as p INNER JOIN p.pf
In the example pf is a property of Person, associated to PhisicalPerson.
class Person {
#OneToOne(mappedBy = "person")
private PhisicalPerson pf;
}
class PhisicalPerson {
#OneToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "fk_person")
private Person person;
}
Related
I have two tables below:
#Entity
#Table(name="COLLEGE")
public class College {
private Long collegeId;
private List<Student> students;
#Id
#Column(name = "COLLEGE_ID")
public Long getCollegeId() {
return this.collegeId;
}
public void setCollegeId(final Long collegeId) {
this.collegeId= collegeId;
}
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "college")
#Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
public List<Student> getStudents() {
if (this.students== null) {
this.students= new ArrayList<>();
}
return this.students;
}
public void setStudents(List<Student> students){
this.students = students
}
}
#Entity
#Table(name="STUDENT")
public class Student {
private Long studentId;
private College college;
private String name;
private String department;
#Id
public Long getStudentId() {
return this.studentId;
}
public void setStudentId(Long studentId) {
this.studentId = studentId;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "COLLEGE_ID")
public getCollege() {
return this.college;
}
public setCollege(College college) {
this.college = college;
}
......
......
}
I want to get the college object with list of students of a specific department. The SQL query is below:
select *
from COLLEGE c
inner join STUDENT s on c.COLLEGE_ID= s.collegeId
where c.COLLEGE_ID=12345 and s.DEPARTMENT="ENGINEERING";
So far I have tried the below JPA query but it is returning multiple College objects.
SELECT DISTINCT c
FROM COLLEGE c
INNER JOIN c.students s
where c.collegeId= :collegeid and s.department = :department
How to return a single college object with list of students with filtered department?
NOTE: I can't alter the entity objects used here.
Try to use this query, using JOIN FETCH instead INNER JOIN:
SELECT DISTINCT c FROM College c
JOIN FETCH c.students s
WHERE c.collegeId= :collegeid
AND s.department = :department
I've been trying to get all rows from table in EclipseLink.
I created my entities from db with the JPA tools. This is the result:
#Entity
#Table(name="employee", schema="hr")
#NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
public Employee() {
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
I found many pages where people create Query object to get all the records but they define again the "select" query like this.
Query q = em.createQuery("select e from Employee e");
But doing a research, finally I found something like this:
public List<Employee> getEmployees() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("ResourcesService");
EntityManager em = factory.createEntityManager();
Query q = em.createQuery("from Employee e", Employee.class);
return q.getResultList();
}
Is there a even more simplified way to query this, just using the class name? Because the mapped entity already contains the select query.
I mean instead of doing this
Query q = em.createQuery("from Employee e", Employee.class);
To do something like this fictional example:
Query q = em.createQuery(Employee.class);
Why not use the named query you have defined?
em.createNamedQuery("Employee.findAll").getResultList();
You could name it "Employee.class" ... :-)
In a spring mvc application using hibernate and MySQL, I am getting an error which seems to indicate that a Name entity cannot find the setter for the id property of the BaseEntity superclass of the Patient entity.
How can I resolve this error?
Here is the error message:
Caused by: org.hibernate.PropertyAccessException: could not set a field value by
reflection setter of myapp.mypackage.Name.patient
Here is the line of code that triggers the error:
ArrayList<Name> names = (ArrayList<Name>) this.clinicService.findNamesByPatientID(patntId);
Here is the BaseEntity, which is the superclass of both Patient and Name:
#Entity
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
#DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'BaseEntity' ELSE dtype END)")
public class BaseEntity {
#Transient
private String dtype = this.getClass().getSimpleName();
#Id
#GeneratedValue(strategy = GenerationType.TABLE)
protected Integer id;
public void setId(Integer id) {this.id = id;}
public Integer getId() {return id;}
public void setDtype(String dt){dtype=dt;}
public String getDtype(){return dtype;}
public boolean isNew() {return (this.id == null);}
}
Here is the Patient entity:
#Entity
#Table(name = "patient")
public class Patient extends BaseEntity{
#OneToMany(mappedBy = "patient")
private Set<Name> names;
protected void setNamesInternal(Set<Name> nms) {this.names = nms;}
protected Set<Name> getNamesInternal() {
if (this.names == null) {this.names = new HashSet<Name>();}
return this.names;
}
public List<Name> getNames() {
List<Name> sortedNames = new ArrayList<Name>(getNamesInternal());
PropertyComparator.sort(sortedNames, new MutableSortDefinition("family", true, true));
return Collections.unmodifiableList(sortedNames);
}
public void addName(Name nm) {
getNamesInternal().add(nm);
nm.setPatient(this);
}
//other stuff
}
Here is the Name entity:
#Entity
#Table(name = "name")
public class Name extends BaseEntity{
#ManyToOne
#JoinColumn(name = "patient_id")
private Patient patient;
public Patient getPatient(){return patient;}
public void setPatient(Patient ptnt){patient=ptnt;}
//other stuff
}
The complete stack trace can be viewed at this link.
The SQL generated by Hibernate for the above query is:
select distinct hl7usname0_.id as id1_0_0_, givennames1_.id as id1_45_1_,
hl7usname0_.family as family1_44_0_, hl7usname0_.patient_id as patient3_44_0_,
hl7usname0_.person_id as person4_44_0_, hl7usname0_.suffix as suffix2_44_0_,
hl7usname0_.usecode as usecode5_44_0_, hl7usname0_.codesystem as codesyst6_44_0_,
givennames1_.given as given2_45_1_, givennames1_.name_id as name3_45_1_,
givennames1_.name_id as name3_0_0__, givennames1_.id as id1_45_0__
from hl7_usname hl7usname0_
left outer join hl7_usname_given givennames1_ on hl7usname0_.id=givennames1_.name_id
where hl7usname0_.patient_id=1
When I run this query through the MySQL command line client, it returns the only record in the test database table.
That's not what the stack trace says. The stack trace doesn't say that the ID can't be set. It says:
Caused by: java.lang.IllegalArgumentException: Can not set org.springframework.samples.knowledgemanager.model.HL7Patient field org.springframework.samples.knowledgemanager.model.HL7USName.patient to org.springframework.samples.knowledgemanager.model.HL7USName
So, your HL7USName class has a field named patient of type HL7Patient, and it's impossible to set this field with a value of type HL7USName.
This means that your database contains a Name that has a foreign key to a row of type Name instead of a row of type Patient.
I will select all the columns from #Embeddable Class Certification. But i cann't select it. how can i do select the Embeddable class.
#Entity
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#ElementCollection
#CollectionTable(name = "Certification", joinColumns = {#JoinColumn(name="user_id")})
private List<Certification> certifications = new ArrayList<Certification>();
public List<Certification> getCertifications() {
return certifications;
}
public void setCertifications(List<Certification> certifications) {
this.certifications = certifications;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
.....
#Embeddable Class Certification
#Embeddable
public class Certification{
private String name;
private String certArt;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCertArt() {
return certArt;
}
public void setCertArt(String certArt) {
this.certArt = certArt;
}
......
If i run the ResultService i get the following exception:
Caused by: java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Error compiling the query [select c from Certification c]. Unknown entity type [Certification].
How can i select the #Embeddable Class?
You would need to retrieve Certification via the real Entity class i.e. Department. One example query could be as below:
select cer from Department dep join dep.certifications cer
Alternatively, you may want to retrieve qualifying Department entities and then fetch certifications using them.
I have a problem, that I would like to explain with the following example:
JPA class Person:
#ManyToMany(mappedBy = "persons")
private List<Car> cars= new ArrayList<>();
public void setCars(List<Car> cars) {
this.cars= cars;
}
public List<Car> getCars() {
return cars;
}
and where the problem shows itself:
Servlet class:
Person person = genericDao.findOne(1);
request.setAttribute("person", person.getName());
List<Car> cars= new ArrayList<Car>();
cars= person.getCars();
request.setAttribute("cars", cars);
The problem is that when trying to get the cars. They aren't automatically retrieved from the database and saved in the array in the Person class. How can I setup a JPA class with a Many to Many relationship, from which I can easily retrieve objects with a relationship.
Car.java
IMPORTS LEFT OUT!
#Entity
#Table(name = "DSD_Cars")
public class Car extends ModifiableEntity {
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#ManyToMany
#JoinTable(
name="DSD_Persons_Cars",
joinColumns = {#JoinColumn(name="IDCar", referencedColumnName = "ID")},
inverseJoinColumns = {#JoinColumn(name = "IDPerson", referencedColumnName = "ID")}
)
private List<Person> persons= new ArrayList<>();
public void setPersons(List<Person> persons) {
this.persons= persons;
}
public List<Persons> getPersons() {
return persons;
}}
The problem has been solved:
The Car class had an #Table(name = "DSD_Cars") annotation. However, the #Table used a wrong import rule. After changing the #Table type to the JPA version, everything worked. It seems JPA uses the class name if the #Table isn't defined properly. That explains the error.
Thanks to everyone who spent time to help me!