Hibernate Criteria. Join / Select when no Assosiation - java

I am using Hibernate version 4.2
I have 2 Entities.
#Entity
public class A {
Long Id;
#ManyToOne
B b;
}
#Entity
public class B {
Long Id;
//There is no relation back here with any annotations to A, and can't add a #OneToMany
}
is it possible todo a Query with Hibernate Criteria to get a result that looks like this.
List<Map<B,List<A>>> ? dosn't matter if it is with a join or a select.
example what i want in result:
A.id B.id
1 1,2,3,4
2
3 5
4 7
5
//Trind

You can use something like below. I don't know whether it is your actual requirement though. Assuming B b is OneToOne, 12 is the id of B,
Criteria c = session.createCriteria(A.class, "a");
c.createAlias("a.b", "b");
c.add(Restrictions.eq("a.b.Id", "12"));
return c.list();
this returns a list of arrays and by using those arrays you can form what you want.

I got help from Christian Bauer who have Written Hibernate in Action.
Criteria from Hibernate:
List<Object[]> result =
session.createCriteria(A.class, "a")
.createAlias("b", "i", JoinType.RIGHT_OUTER_JOIN)
.setResultTransformer(PassThroughResultTransformer.INSTANCE)
.list();

Related

using enum list as parameter in HQL query

I have an entity called Band with a attribute List<Genres> genres, Genres is a ENUM with the following values: ALTERNATIVE_ROCK("Alternative Rock"), CLASSIC_ROCK("Classic Rock"), HARD_ROCK("Hard Rock"), HEAVY_METAL("Heavy Metal"),PROGRESSIVE_ROCK("Progressive Rock");
I'm trying to create a method that returns a List<Band> using an List<Genres> as parameter using HQL, something like:
public List<Band> listBandsPerGenres(List<Genres> genres);
But i'm receiving some errors with HQL queries that i'd tried?
Above some hql queries that i've tried...
Query q = getSession().createQuery("SELECT b FROM Band b JOIN FETCH b.genres g WHERE g IN (?)");
q.setParameter(0, genres);
return q.list();
returns an error saying that an ArrayList cannot be cast to Enum...
or...
"SELECT b FROM Band b JOIN FETCH b.genres g WHERE g.value IN (?)"
returns an error like : dereference scalar collection element ENUM
property genres mapping, entity Band...
#Basic(optional=false)
#Enumerated(EnumType.STRING)
#ElementCollection(targetClass=Genres.class)
#CollectionTable(name="banda_generos", joinColumns=#JoinColumn(name="id_banda", nullable=false))
private List<Genres> genres;
This works for Hibernate 4
Query q = s
.createQuery("SELECT b FROM Q27715453$Band b JOIN b.genres g WHERE g IN (:genres)");
q.setParameterList("genres", Arrays.asList(Genres.ROCK, Genres.CLASSIC));
System.out.println(Arrays.toString(q.list().toArray()));
Check that the method Query#setParameterList is used instead of Query#setParameter, also it's used g insted of g.value.
I don't think you can do that. According to JPA spec (section 4.6.9. page 185) lists aren't supported as left-side operand with IN expression.

Hibernate criteria with 2 entities table and 1 association table

I need to make a query inside a DAO using hibernate criteria, but im not sure how.
I have 2 entities, A and B, and an association table, that contains both A and B ID's.
A doesnt know B, and B doesnt know A.
I want to find all A's that are associated with a certain B, using criteria.
I made a diagram, hope it helps to explain.
Example image
As you can see, table A have 3 records, table B have 3 records too and table AssocAB 3 records as well. I want to find all A's that are associated in AssocAB with B1. The query should return A1 and A3.
is it possible?
Here's the classes, and the relationship annotated.
Entity A: No annotation
Entity B: Have a Set of Entity A
#ManyToMany
#JoinTable(name = "Assoc_AB", joinColumns = { #JoinColumn(name = "ID_B")}, inverseJoinColumn = { #JoinColumn(name = "ID_A")})
#ForeignKey(name = "FK_A_B", inverseName = "FK_B_A")
public set<A> getA(){
return this.listOfA;
}
And no class for association class, the mapping on B creates the assoc table.
Thanks in advance.
I tried to write a criteria query with your indications, but it's not easy because you tell that A and B tables have a int ID, but then you put Strings in your rows ("A1", "B1"...). I supposed that your id is a String instead of an int. You should have something like this:
List<A> listOfA = new ArrayList<A>();
Criteria criteria = session.createCriteria(B.class, "b");
criteria.add(Restrictions.eq("b.id", "B1"));
List<B> listOfBs = criteria.list();
for (B b : listOfBs) {
listOfA.addAll(b.getA());
}
If you have a name property in B class, you would have to modify the restriction:
criteria.add(Restrictions.eq("b.name", "B1"));
I hope this code can help you solve your problem.

Hibernate criteria query multiple criteria

In my current project I've faced a problem of getting entities with hibernate criteria query. I have the following entities:
Professor, which contains a list of students
Student, which contains a list of assignments.
Assignment, which contains id of student to which it is assigned to.
Now, I want to get all assignments relative to the professor, i.e. all assignments Professor assigned to his students.
This query shows what I want to implement in criteria query.
select * from Assigment p, Student a, Professor c where p.studentid = a.id and a.proffid = c.id and c.id = 2411;
How can I implement this query using hibernate criteria API?
suppose your tables like that:
#Entity
public class Professor{
K id;
List<Student> students;
}
#Entity
public class Student{
K profid;
List<Assignments> assignments;
}
#Entity
public class Assignments{
K studentid;
}
simple sample by using alias:
Criteria criteria = currentSession.createCriteria(Professor.class, "professor");
criteria.createAlias("professor.students", "student");
criteria.createAlias("student.assigments", "assigment");
criteria.add(Restrictions.eqProperty("professor.id", "student.profid"));
criteria.add(Restrictions.eqProperty("assigment.studentid", "student.profid"));
criteria.add(Restrictions.eq("id", 2411));
return criteria.list();

How in hql query select part of object?

I need tune query for performance. The tree of objects like:
classA {
classB b;
classC c;
.....}
I need select similar to SQL:
select a.field1, b.field2, c.field3, c.field4 from a left outer join b
on a.id=b.fk left outer join c on b.id=c.fk
I don't understand what kind of result will be returned, does it arrayList? Or query returns
all 3 objects?
Thanks.
It will be
List<Object[]> list = new ArrayList<Object[]>();
The result which would be returned by the query would be type of -
List<Object[]>
If you use HQL I think you use hibernate. Provide mapping with relations (ManyToOne or OneToOne) to your objects:
class A {
#ManyToOne
pribvate B b;
#OneToOne
private C c;
}
Then use session methods to select your object A with hql query of criteria. Hibernate do all joins for you automatically. And it will return List of A.

How to create a JPA query with LEFT OUTER JOIN

I am starting to learn JPA, and have implemented an example with JPA query, based on the following native SQL that I tested in SQL Server:
SELECT f.StudentID, f.Name, f.Age, f.Class1, f.Class2
FROM Student f
LEFT OUTER JOIN ClassTbl s ON s.ClassID = f.Class1 OR s.ClassID = f.Class2
WHERE s.ClassName = 'abc'
From the above SQL I have constructed the following JPQL query:
SELECT f FROM Student f LEFT JOIN f.Class1 s;
As you can see, I still lack the condition OR s.ClassID = f.Class2 from my original query. My question is, how can I put it into my JPQL?
Write this;
SELECT f from Student f LEFT JOIN f.classTbls s WHERE s.ClassName = 'abc'
Because your Student entity has One To Many relationship with ClassTbl entity.
If you have entities A and B without any relation between them and there is strictly 0 or 1 B for each A, you could do:
select a, (select b from B b where b.joinProperty = a.joinProperty) from A a
This would give you an Object[]{a,b} for a single result or List<Object[]{a,b}> for multiple results.
Normally the ON clause comes from the mapping's join columns, but the JPA 2.1 draft allows for additional conditions in a new ON clause.
See,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#ON
Please see :
public interface YourDBRepository extends JpaRepository<Employee, Long> {
#Query("select new com.mypackage.myDTO(dep.empCode, dep.empName, em.EmployeeCode, em.EmployeeName) \n" +
"from Department dep\n" +
"left join Employee em\n" +
"on dep.DepartmentCode = em.DepartmentCode") // this is JPQL so use classnames
List<myDTO> getDeptEmployeeList();
}
You can also use CrudRepository and include #JoinColumn with FK table class in PK table class and have List return list and then do find operation to achieve the same.
In Department entity class:
#OneToMany
#Fetch(FetchMode.JOIN)
#JoinColumn(name="DEPT_CODE")
private List<Employee> employees;
CriteriaBuilder is yet another option.

Categories