I have a scenario where I need to load all the child values in one case and some specific child values in other . I am using a single bean for both the cases and writing the queries using named query.
#namedqueries{
#namedQuery(name="query1") = "select parent from Parent parent",
#namedQuery(name="query2") = "select parent from Parent parent",
}
Class Parent {
#manytomany
#join mentioned my join condition here //
List<Child> child ;
}
Class Child
{
String A;
String B;
String C;
#manytomany(mappedby = "child")
List<parent> parent ;
}
Now in my query 2 I need to load only String A not String B and String C .
I tried using
"select parent.child .A from Parent parent" as Query 2
but getting the below error
"Attempting to navigate to relation field via multi-valued association and
jpql doesnt allow traversal through multi valued relationship. Try join instead"
So any suggestions on how to proceed on this ..
1) Should I have to create a new bean for each Query
2) Or Can we control the child object parameters in specific named queries
You are accessing a collection when you say select parent.child and you can't say select parent.child.A this is wrong according HQL standards. You need to do this using join as the error message is suggesting:
select c.A from parent as p join p.child as c
Then no, you don't have to create a new bean for each query.
Related
I have two JPA entities
class A{
#OneToMany
Lis<B> entitiesB;
#Column("STATUS")
String status;// will sort based on this column
}
and
class B{
#ManyToOne
A entityA;
#Column("PROPERTY_ONE")
String propertyOne;
....
#Column("PROPERTY_M")
String propertyM;
....
}
I need to left join A with B and then perform filtering on columns from B. I have the following criteria:
Join<A, B>root=criteriaBuilder
.createQuery(A.class)
.from(A.class)
.join("entitiesB");
CriteriaQuery<A> query = criteriaBuilder.createQuery(A.class);
query.select(query.from(A.class).join("entitiesB"))
.distinct(true)
.where(formWhereClause(filters))
.orderBy(formOrderByClause());
How do I form the filter by the status property from A entity
criteriaBuilder.notEqual(root.get("A").get("status"), "SOME_STATUS_VALUE");
It has generated me the following SQL:
select distinct generatedAlias0 from A as generatedAlias1
inner join generatedAlias1.entitiesB as generatedAlias0
where ( generatedAlias2.A.status<>:param0 ) and ( generatedAlias2.propertyOne like :param1 )
order by generatedAlias2.propertyM desc
I got the following exception:
'org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException:
Invalid path generatedAlias2.A.status '
How can I fix it? I am using Hibernate 4.3.5 as the persistence provider.
CriteriaQuery query = criteriaBuilder.createQuery(A.class);
means that you want to return instances of type A. Therefore, your select clause must specify query root instead of an instance of Join as you did:
Define the root of the query because the join method can only be applied either to an instance of Root or Join types:
Root<A> root = query.from(A.class);
Define Join (I need to left join A with B):
Join<A, B> b = root.join("entitiesB", JoinType.LEFT);
Define the SELECTclause:
query.select(root)
.distinct(true)
.where(formWhereClause(filters))
.orderBy(formOrderByClause());
How do I form the filter by the status property from A entity
Form it as follows:
criteriaBuilder.notEqual(root.get("status"), "SOME_STATUS_VALUE");
and if you want to use attributes of B as a filter define it, for example, as:
criteriaBuilder.equal(b.get("propertyOne"), "SOME_VALUE");
Can any one tell me why addEntity is not identifying separate column from alias? Both parent and child getting child value only. parents field is getting override by child filed.
If I keep pr.* first in select statement then it take parent value in both object.
My code is as below.
String sql="select ch.*,pr.* from users as ch inner join users as pr on ch.parent_id=pr.id";
Query
query=session.createSQLQuery(sql).addEntity("ch",UserDTO.class).addEntity("pr",UserDTO.class);
List<Object> result=query.list();
Object[] objects = (Object[])result.get(0);
UserDTO child=(UserDTO)objects[0];
UserDTO parent=(UserDTO)objects[1];
I have read this doc hibernate doc, it is suggesting to use as follow. But {} is not working in mysql select.
sess.createSQLQuery("SELECT {cat.*}, {mother.*} FROM CATS c, CATS m WHERE c.MOTHER_ID = c.ID")
.addEntity("cat", Cat.class)
.addEntity("mother", Cat.class)
I've stumbled upon a problem with Hibernate. I've 2 entities - let's say A and B like so (Entity/Table annotations ommited):
class A {
#ManyToOne
#JoinColumn(name = "b_id")
private B b;
}
class B {
#Column(name = "name")
private String name;
}
Now, I'm trying to query all A entities and ordering them by name field of B's entity like so:
SELECT q FROM A AS q ORDER BY q.b.name asc nulls last
The problem is, there are rows in A's table having null foreign-key (b is null) - in result the aforementioned query returns only rows that don't contain null in b field, and I'd like to have them all.
I guess hibernate joins the table without using LEFT JOIN (OUTER JOIN?) resulting in null values being skipped.
Is there any way to change this behaviour? It would be great, if I could solve it by using annotations in entity classes, because the query-generating mechanism is pretty locked up.
You can use CriteriaBuilder and set alias on entityRoot
Root<A> entityRoot = criteriaQuery.from(A);
entityRoot.join("b", JoinType.LEFT).alias("b");
criteriaQuery.select(entityRoot)
.orderBy(criteriaBuilder.asc(entityRoot.get("b").get("name"))
;
you can use criteria query for this but you will have to create session while using that, it is simpler to access database using criteria:
Criteria criteria = session.createCriteria(A.class)
//create alias of your other class to provide ordering according to foriegn key
criteria.createAlias("foreignkey","keyin table A(eg..b)");
criteria.addOrder(Order.asc(b.name));
List list = criteria.getlist();
hope this helps
I have two entities, whith OneToMany relationship:
class Parent {
int parentId;
Set<Children> children;
}
class Child {
int childId;
}
and the following HQL query:
"SELECT p.children FROM Parent p left join p.children as c WHERE p.id=:pid AND c.id:=cid"
is returning me all children of the parent with given id, while I would expect only a child with id matching given child id. What am I doing wrong here?
You need to use inner join instead of left join.
Try either of the below, not sure of exact syntax.
SELECT p.children FROM Parent p inner join p.children as c WHERE p.id=:pid AND c.id:=cid
or
SELECT p.children FROM Parent p, p.children as c WHERE p.id=:pid AND c.id:=cid
I want to annotate following structure:
I have this query:
SELECT A.*, BES.*, BES_2.*
INNER JOIN BES ON A.a = BES.a AND A.b = BES.b
INNER JOIN BES AS BES_2 ON A.a = BES_2.a AND A.b = BES_2.b
WHERE (BES.c = N'foo') AND (BES_2.c = N'bar')
I have the entities Job (representing A) and JobEndPoint (representing BES). The Job object should contain two JobEndPoint which map like a one-to-one relation. I need two JOIN the table two times checking for the same values only differed by the column "c" which I check in the WHERE statement.
#OneToOne
private JobEndPoint from;
#OneToOne
private JobEndPoint to;
My problem is now that the database columns and the object fields differ a lot and I don't know how to add the WHERE statement.
Create a JPA repository, and type a custom #Query.
I assume you already linked the parent and JobEndPoint classes over a and b fields. (To do that, define a multiple-column id on JobEndPoint and specify joinColumns in the parent class.)
#Query("SELECT u FROM parent
LEFT JOIN u.from bes
LEFT JOIN u.to bes2
WHERE bes.c = 'foo'
AND bes2.c = 'bar'")
Set<Parent> findMatchingParents()