inner join in hibernate - java

I am just a beginner in Hibernate, I would like to execute this query but I don't know how .. any help please?
SELECT DISTINCT agents.username
FROM users u
INNER JOIN UserDistributors ud
ON u.id = ud.[user]
INNER JOIN users agents
ON agents.type =9
INNER JOIN UserDistributors agentsdistributor
ON agentsdistributor.distributor = ud.distributor
AND agents.id=agentsdistributor.[user]
WHERE u.id=1778
my user.hbm file has one to many relation to distributor
<set name="userDistributors" table="UserDistributors"
inverse="true" lazy="true" fetch="select">
<key>
<column name="[user]" not-null="true" />
</key>
<one-to-many class="net.tedata.dp.model.UserDistributors" />
</set>

Try this
Criteria c = session.createCriteria(User.class);
c.createAlias("ud", "UserDistributors"); // inner join by default
c.add(Restrictions.eq("ud.id", "<Name>"));

Related

How to access joined-subclass's properties in HQL?

Consider the following hibernate mapping (using hibernate 4):
Answer with a DataCollection joined-subclass:
<hibernate-mapping>
<class name="Answer" table="answer">
<many-to-one name="answeredForm" class="AnsweredForm" fetch="select">
<column name="answered_form_id" />
</many-to-one>
<joined-subclass table="data_collection" name="DataCollection" extends="Answer">
<key column="id"></key>
</joined-subclass>
</class>
</hibernate-mapping>
AnsweredForm with a PatientForm joined-subclass:
<hibernate-mapping>
<class name="AnsweredForm" table="answered_form">
<joined-subclass table="patientForm" name="PatientForm" extends="AnsweredForm">
<many-to-one name="patient" class="Patient" fetch="join">
<column name="patient_id" />
</many-to-one>
</joined-subclass>
</class>
</hibernate-mapping>
Question: Using HQL, how can you ask for "all datcollections whose AnsweredForm belongs to patient x"?
SELECT answer FROM DataCollection answer
JOIN answeredForm answeredForm
WHERE answer.answeredForm.patient.code=:patientCode
This HQL yields the error:
ERROR: missing FROM-clause entry for table "answeredfo2_2_"
And rightly so, as the SQL translation of this query is:
SELECT datacollec0_.id AS id1_62_,
datacollec0_1_.free_text AS free_tex2_62_
FROM data_collection datacollec0_
INNER JOIN answer datacollec0_1_
ON datacollec0_.id = datacollec0_1_.id
CROSS JOIN answered_form answeredfo1_
CROSS JOIN answered_form answeredfo2_
CROSS JOIN patient patient3_
WHERE datacollec0_1_.answered_form_id = answeredfo1_.id
AND datacollec0_1_.answered_form_id = answeredfo2_.id
AND answeredfo2_2_.patient_id = patient3_.id
AND CASE
WHEN answeredfo1_4_.id IS NOT NULL THEN 4
WHEN answeredfo1_1_.id IS NOT NULL THEN 1
WHEN answeredfo1_2_.id IS NOT NULL THEN 2
WHEN answeredfo1_3_.id IS NOT NULL THEN 3
WHEN answeredfo1_.id IS NOT NULL THEN 0
END = 2
AND patient3_.code = ?
Try to use the following hql:
SELECT a FROM Answer a
JOIN a.answeredForm af
WHERE af.patient.code=:patientCode
Look at this part of the hibernate documentation for additional explanations and examples.

Hibernate Criteria do not add schema to table

I have three tables device , vehicle and vehicle_device all tables are in one schema 'tcm' and I'm trying to get 'vehicle' by 'device imei' . In Vehicle.class i have field 'Set devices' and create maping:
Vehicle.hbm.xml
<hibernate-mapping package="hibernate.entity">
<class name="Vehicle" table="vehicles" schema="tcm">
<id name="id" type="integer" column="id">
<generator class="sequence">
<param name="sequence">tcm.vehicles_id_seq</param>
</generator>
</id>
.
.
.
<set name="devices" table="vehicle_device"
inverse="false" lazy="true" fetch="select" cascade="all" >
<key>
<column name="vehicle_id" not-null="true" />
</key>
<many-to-many entity-name="hibernate.entity.Device">
<column name="device_id" not-null="true" />
</many-to-many>
</set>
</class>
when execute criteria to take the results for needed 'device imei'
#Override
public Vehicle getVehicleByDeviceImei(String imei) {
Criteria criteria = getSession().createCriteria(Vehicle.class);
criteria.createAlias("devices", "devices").add(Restrictions.eq("devices.imei", imei));
Vehicle v = (Vehicle) criteria.uniqueResult();
return v;
}
Everything is OK except that the query that is generated does not add schema 'tcm' for the link table 'vehicle_device' in first inner join
select .
.
.
.
from
tcm.vehicles this_
inner join
vehicle_device devices3_
on this_.id=devices3_.vehicle_id
inner join
devices devices1_
on devices3_.device_id=devices1_.id
where
devices1_.device_imei=?
and have an error :
ERROR: relation "vehicle_device" does not exist
LINE 17: vehicle_device devices3_
If i add manual schema to generated query --> 'tcm.vehicle_device' it work.
how to fix my configuration so Hibernate Criteria adds the schema for table 'vehicle_device'.
I fix problem. I just added scheme = 'tcm' in set tag in mapping

Hibernate-Foreign key object Null on Select Query

I have two tables ex:User and Role. with many-to-one relation between User and Role (one User can contain many Roles)
I used SQL query to insert the data in to the User table with the role_id(assume pk of Role table) as foreign key.
Now,when I tried to fetch the records of User with a particular role.
i am using following code to fetch the User object.
User user=(User)session.get('User.class',user_id);
Role role=user.getRole();
On executing the above lines,some times I'm getting the User Object,some times not.
The relation mapping between the objects is as below.
<many-to-one name="role" class="com.example.Role" fetch="select">
<column name="role_id" precision="14" scale="0" />
</many-to-one>
<set name="user" cascade="delete" table="User" >
<key>
<column name="role_id" not-null="true" />
</key>
<one-to-many class="com.example.User" />
</set>
Is there any way to prevent it occuring?
Is this possible that some times the select query will give me output and sometimes null.
There seem to be a fundamental mistake in your design. You stated that one User can contain Many Roles. This means foreign key (which points the PK of User) should be in Roles. But you seem to have put the foreign key in User.
Aside from DUKE answer who clearly pointed that your mapping says that a Role has many users as opposed to your requirement, there are still some issues with your code:
First you need to add inverse="true" to your one-to-many side. Since you have a bi-directional association, only one side can own the relationship:
<set name="user" cascade="delete" table="User" inverse="true">
<key>
<column name="role_id" not-null="true" />
</key>
<one-to-many class="com.example.User" />
</set>
And then it's much more efficient to fetch the Role in the same query with the User:
User user = (User)
session.createQuery(
"select u from User left join fetch u.role where u.id = :user_id')
.setParameter("user_id", user_id)
.uniqueResult();

Hibernate Adding where clause on one-to-many mapping

I have this set on my .hbm file.
<set name="subTopicsTb" table="subtopics_tb" inverse="true" lazy="false" fetch="select">
<key>
<column name="topic_id" />
</key>
<one-to-many class="com.topics.model.SubTopics" />
</set>
now, the default is that, hibernate get's all subtopics where the topic_id is the id.
i want to filter the subtopics. adding something like where subTopics.date is not null thanks
This actually works, being date the column name in your DB. where attribute in the set appends raw sql to your query, so you have to specify as it is in your database and NOT HQL:
<set name="subTopicsTb" table="subtopics_tb" inverse="true" lazy="false"
fetch="select" where="date is not null">
<key>
<column name="topic_id" />
</key>
<one-to-many class="com.topics.model.SubTopics" />
</set>
Add a where clause? I don't know how you set that in an XML config .. but you can check out the annotation version here.
I found something at stackoverflow on how to add the where to your XML.
Are you using HQL to retrieve your SubTopics? If so, you can include the filter in your selection. For example:
String query = "FROM SubTopic subtopic WHERE subtopic.date != null"

Get entries in intersection table based on key

I have three tables:
offers; offer_groups; offer_group_members.
The offers and offer_groups tables are mapped with hibernate (see below).
In offer_group_members, I store to which group the offers belong (offer primary key, offer group primary key).
I am kinda new to hibernate so my question is: How can I get all the OfferGroups from the OFFER_GROUP_MEMBERS table based on the Offer key?
I tried something like this:
Criteria crit;
crit = getSession().createCriteria(Offer.class);
crit = crit.createCriteria("offerGroups");
crit.add(eq("key", offerKey));
Here are the mappings:
for offer:
<composite-id name="comp_id"
class="com.infonova.psm.hibernate.prodsrv.OfferPK">
<key-property name="key" column="KEY"
type="java.lang.String" length="128">
</key-property>
</composite-id>
for offer_group_key:
<id name="key" type="java.lang.String" column="KEY" length="128">
<generator class="assigned"/>
</id>`
for offer_group_key:
<set name="offers" table="OFFER_GROUP_MEMBERS" lazy="true" inverse="false"
cascade="none">
<key>
<column name="OFFER_GROUP_KEY"/>
</key>
<many-to-many class="Offer">
<column name="OFFER_KEY"/>
</many-to-many>
</set>
for offer:
<set name="offerGroups" table="OFFER_GROUP_MEMBERS"
inverse="true" lazy="true" cascade="none">
<key>
<column name="OFFER_KEY" />
</key>
<many-to-many
class="OfferGroup">
<column name="OFFER_GROUP_KEY" />
</many-to-many>
</set>
It would be easier if you showed us the entities, since it's on them that HQL and criteria queries work.
Anyway, in HQL:
select og from Offer o
inner join o.offerGroups og
where o.key = :key
And in Criteria, unfortunately, IIRC, all you can do is select the root entity or scalars, so it's hard to do this without having a bidirectionall association. If you had a bidirectional association, you could do
Criteria c = session.createCriteria(OfferGroup.class, "og");
c.createAlias("og.offers", "o");
c.add(Restrictions.eq("o.key", key));
Since you don't have the bidirectional association, the only way that I know of is to do this:
Criteria c = session.createCriteria(OfferGroup.class, "og");
DetachedCriteria dc = DetachedCriteria.forClass(Offer.class, "o");
dc.createAlias("o.offerGroups", "og2");
dc.add(Restrictions.eq("o.key", key));
dc.setProjection(Projections.property("og2.id"));
c.add(Subqueries.propertyIn("og.id", dc));
which corresponds to this ugly HQL query:
select og from OggerGroup og
where og.id in (select og2.id from Offer o
inner join o.offerGroups og2
where o.key = :key)
For such simple static queries, I don't see any reason to go with Criteria rather than HQL.

Categories