Hibernate 1 to M restriction on children - java

I have 1 to M association with Country and Person. Meaning a Country can have multiple persons. The country.hbm.xml fils is shown below:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.hibernate">
<class name="Country">
<id name="countryId" column="CountryID" > </id>
<property name="countryName" column="CountryName" length="50"></property>
<set name="persons" table="Person" fetch="select" inverse="true">
<key>
<column name="CountryId" not-null="true"></column>
</key>
<one-to-many class="com.test.hibernate.Person"/>
</set>
</class>
</hibernate-mapping>
The Person.hbm.xml is shown below
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.test.hibernate">
<class name="Person">
<id name="personID" column="PersonID" > </id>
<property name="name" column="Name" length="50"></property>
<property name="age" column="Age"></property>
<property name="gender" column="Gender" length="1"></property>
<property name="email" column="Email" length="50"></property>
<property name="countryID" column="CountryID" insert="false" update="false"></property>
<many-to-one name="Country" class="com.test.hibernate.Country" fetch="select">
<column name="CountryID" not-null="true"></column>
</many-to-one>
</class>
</hibernate-mapping>
Now, I am trying to query all the persons who are males belonging to India Country
Criteria countryCriteria = session.createCriteria(Country.class);
Criterion country = Restrictions.eq("countryName", "India");
Criterion male = Restrictions.eq("persons.gender", "M");
countryCriteria.add(country);
countryCriteria.add(male);
List<Country> countryList = countryCriteria.list();
I am getting a
Exception in thread "main" org.hibernate.QueryException: could not resolve property: persons.gender of: com.test.hibernate.Country
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:83)
at org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:98)
at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:61)
at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1960)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:523)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.findColumns(CriteriaQueryTranslator.java:538)
at org.hibernate.criterion.SimpleExpression.toSqlString(SimpleExpression.java:66)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getWhereCondition(CriteriaQueryTranslator.java:419)
at org.hibernate.loader.criteria.CriteriaJoinWalker.(CriteriaJoinWalker.java:123)
at org.hibernate.loader.criteria.CriteriaJoinWalker.(CriteriaJoinWalker.java:92)
at org.hibernate.loader.criteria.CriteriaLoader.(CriteriaLoader.java:95)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1643)
at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374)
at com.test.hibernate.Main.main(Main.java:54)
Please help. I am new to Hibernate.
Thanks in advance.

Country.personsis of type Collection<Person>. A Collection doesn't have any property named "gender".
If you used HQL instead of Criteria (and you should, for such a simple static query), you would have to do a join:
select c from Country c
join country.persons person
where c.countryName = 'India'
and person.gender = 'M'
You thus have to do the same with the Criteria query:
Criteria countryCriteria = session.createCriteria(Country.class, "c");
countryCriteria.createALias("c.persons", "person");
countryCriteria.add(Restrictions.eq("c.countryName", "India"));
countryCriteria.add(Restrictions.eq("person.gender", "M"));
List<Country> countryList = countryCriteria.list();

I used M to 1 and used Criteria on Person object as opposed to Country Object.
Criteria personCriteria = session.createCriteria(Person.class,"p");
personCriteria.createAlias("p.Country", "c");
Criterion gender = Restrictions.eq("gender", "M");
Criterion country = Restrictions.eq("c.countryName", "India");
personCriteria.add(gender);
personCriteria.add(country);
List<Person> personList = personCriteria.list();
This way the personList had all the Persons who were males and belonged to India.

Related

How to fix org.hibernate.MappingException unmapping class

EDIT :
The problem solved,I didnt write the exactly loaction of the entites in the XML files,Where the one-many-tag.
Im trying to map these classes to database and i get this error :
Exception in thread "main" org.hibernate.MappingException: Association references unmapped class: Reservation
at org.hibernate.cfg.HbmBinder.bindCollectionSecondPass(HbmBinder.java:2557)
at org.hibernate.cfg.HbmBinder$CollectionSecondPass.secondPass(HbmBinder.java:2808)
at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:70)
at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1695)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at entities.chairandtabletest.main(chairandtabletest.java:39)
I tried to find where is my problem,I read about this exception and i dont understand where is the problem in my program.
The classes :
public class Customer {
private Integer id;
private String fullName;
private String address;
private String email;
private String phoneNumber;
private List<Reservation> reservations = new ArrayList<Reservation>();
}
public class Reservation{
private Integer id;
private String date;
private Integer totalSum;
private boolean isDeliever;
private List<Item> items = new ArrayList<Item>();
}
public class Item {
private Integer id;
private String name;
private Integer price;
}
The tables :
CREATE TABLE ITEM(
item_id INT NOT NULL AUTO_INCREMENT,
item_name VARCHAR(40),
item_price INT NOT NULL,
reservation_id INT,
PRIMARY KEY(item_id)
);
CREATE TABLE RESERVATION(
reservation_id INT NOT NULL AUTO_INCREMENT,
reservarion_date VARCHAR(255),
reservtion_delivery BOOL,
reservation_total_sum INT,
customer_id INT,
PRIMARY KEY(reservation_id)
);
CREATE TABLE CUSTOMERS(
customer_id INT NOT NULL AUTO_INCREMENT,
customer_full_name VARCHAR(40),
customer_address VARCHAR(255),
customer_email VARCHAR(255),
customer_phone_number VARCHAR(20),
PRIMARY KEY(customer_id)
);
The XML files :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/chairandtable?serverTimezone=UTC</property>
<property name="hibernate.connection.username">aliali</property>
<property name="hibernate.connection.password">password</property>
<mapping resource="props/customer.hbm.xml"/>
<mapping resource="props/reservation.hbm.xml"/>
<mapping resource="props/item.hbm.xml"/>
</session-factory>
</hibernate-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entities.Customer" table="customers">
<meta attribute="class-description">
This class contain customers details.
</meta>
<id name="id" type="integer" column="customer_id">
<generator class="identity"/>
</id>
<bag name="reservations" cascade="all">
<key column= "customer_id"/>
<one-to-many class="Reservation"/>
</bag>
<property name="fullName" column="customer_full_name" type="string"/>
<property name="address" column="customer_adress" type="string"/>
<property name="email" column="customer_email" type="string"/>
<property name="phoneNumber" column="customer_phone_number" type="string"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name ="entities.Reservation" table="reservation">
<meta attribute="class-description">
This class contain reservation detail.
</meta>
<id name ="id" column="reservation_id" type="integer">
<generator class="identity"/>
</id>
<bag name="items" cascade="all">
<key column="reservation_id"/>
<one-to-many class="Item"/>
</bag>
<property name="date" column="reservation_date" type="string"/>
<property name="totalSum" column="reservation_total_sum" type="integer"/>
<property name="isDeliver" column="reservtion_delivery" type="boolean"/>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="entities.Item" table="item">
<id name= "id" column="item_id" type="integer">
<generator class="identity"/>
</id>
<property name="name" column="item_name" type="string"/>
<property name="price" column="item_price" type="integer"/>
</class>
</hibernate-mapping>
I think the problem is the tables i declared , Maybe the are not matching the
xml file.
You need to change the order of *hbm.xml configs to:
<mapping resource="props/item.hbm.xml"/>
<mapping resource="props/reservation.hbm.xml"/>
<mapping resource="props/customer.hbm.xml"/>
And add the "entities" package to all of your one-to-many mappings like this:
<one-to-many class="entities.Item"/>

Hibernate simultaneous many-to-many and many-to-one mapping

I have a question about the creation of database schemes by Hibernate.
In our project we have users and groups. Groups have exactly one owner and can have multiple members. A user can be owner and member of multiple groups.
We came up with the following Hibernate mapping:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="model.User" table="ProductUser">
<id name="id" column="userId">
<generator class="native"/>
</id>
<property name="email"/>
<property name="firstName"/>
<property name="lastName"/>
<set name="ownedUserGroups" table="UserGroup" inverse="true">
<key column="userId"/>
<one-to-many class="model.UserGroup"/>
</set>
<set name="userGroups" table="Members" inverse="false" lazy="true" fetch="select">
<key column="userId"/>
<many-to-many column="userGroupId" class="model.UserGroup"/>
</set>
</class>
<class name="model.UserGroup" table="UserGroup">
<id name="id" column="userGroupId">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="owner" class="model.User" column="owner_UserId"/>
<set name="members" table="Members" inverse="true" lazy="true" fetch="select">
<key column="userGroupId"/>
<many-to-many column="userId" class="model.User"/>
</set>
</class>
</hibernate-mapping>
The database scheme Hibernate creates for us looks the following:
Database scheme created by Hibernate
Can somebody explain why usergroup has the userid as a foreign key? (As you can see in the image)
For the sake of completeness, here is the code for User and UserGroup:
public class User {
private int id;
private String firstName;
private String lastName;
private String email;
private Set<UserGroup> ownedUserGroups;
private Set<UserGroup> userGroups;
public User() {
this.ownedUserGroups = new HashSet<>();
this.userGroups = new HashSet<>();
}
public User(String firstName, String lastName, String email) {
this();
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
// getters and setters
}
public class UserGroup {
private int id;
private String name;
private User owner;
private Set<User> members;
public UserGroup() {
this.members = new HashSet<>();
}
public UserGroup(String name, User owner, HashSet<User> members) {
this.name = name;
this.owner = owner;
this.members = members;
}
// getters and setters
}
Ok. The problem is with your many-to-one-mapping. What your doing is your trying to set ownedUserGroups to all the groups where the userId equals the id of the current user. However you need to look for all groups where the owner_UserId equals the id of your user. Basically you just need to replace userId with owner_UserId. Your final mapping file should look like this:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="model.User" table="ProductUser">
<id name="id" column="userId">
<generator class="native"/>
</id>
<property name="email"/>
<property name="firstName"/>
<property name="lastName"/>
<set name="ownedUserGroups" table="UserGroup" inverse="true">
<key column="owner_userid"/> <!-- CHANGED -->
<one-to-many class="model.UserGroup"/>
</set>
<set name="userGroups" table="Members" inverse="false" lazy="true" fetch="select">
<key column="userId"/>
<many-to-many column="userGroupId" class="model.UserGroup"/>
</set>
</class>
<class name="model.UserGroup" table="UserGroup">
<id name="id" column="userGroupId">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="owner" class="model.User" column="owner_UserId"/>
<set name="members" table="Members" inverse="true" lazy="true" fetch="select">
<key column="userGroupId"/>
<many-to-many column="userId" class="model.User"/>
</set>
</class>
</hibernate-mapping>

StackOverflowError when tried to convert criteria list result into json

I have created an application for converting the Hibernate criteria list results into json, first whe i tried i got Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter
I resolved that when i googled i came across this stuff Could not serialize object cause of HibernateProxy
Now i am getting the StackOverflowError as shown below
INFO: HHH000397: Using ASTQueryTranslatorFactory
Hibernate:
select
this_.id as id1_1_0_,
this_.base_id as base_id2_1_0_,
this_.name as name3_1_0_
from
testdatabase12.child this_
Hibernate:
select
base0_.id as id1_0_0_,
base0_.name as name2_0_0_
from
testdatabase12.base base0_
where
base0_.id=?
Hibernate:
select
childs0_.base_id as base_id2_0_0_,
childs0_.id as id1_1_0_,
childs0_.id as id1_1_1_,
childs0_.base_id as base_id2_1_1_,
childs0_.name as name3_1_1_
from
testdatabase12.child childs0_
where
childs0_.base_id=?
Exception in thread "main" java.lang.StackOverflowError
at java.util.LinkedHashMap$LinkedHashIterator.<init>(LinkedHashMap.java:345)
at java.util.LinkedHashMap$LinkedHashIterator.<init>(LinkedHashMap.java:345)
at java.util.LinkedHashMap$ValueIterator.<init>(LinkedHashMap.java:387)
at java.util.LinkedHashMap$ValueIterator.<init>(LinkedHashMap.java:387)
at java.util.LinkedHashMap.newValueIterator(LinkedHashMap.java:397)
at java.util.HashMap$Values.iterator(HashMap.java:910)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:203)
at com.dao.HibernateProxyTypeAdapter.write(HibernateProxyTypeAdapter.java:52)
at com.dao.HibernateProxyTypeAdapter.write(HibernateProxyTypeAdapter.java:1)
:
:
My code is as given below
App.java
public class App {
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
List names = session.createCriteria(Child.class).list();
GsonBuilder b = new GsonBuilder();
b.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY);
Gson gson = b.create();
String jsonNames = gson.toJson(names);
System.out.println("jsonNames = " + jsonNames);
session.close();
}
}
Base.java
public class Base implements java.io.Serializable {
private Integer id;
private String name;
private Set childs = new HashSet(0);
// getters and setters
}
Base.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 2, 2014 5:23:25 AM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.mappings.Base" table="base" catalog="testdatabase12">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" length="20" />
</property>
<set name="childs" table="child" inverse="true" lazy="true" fetch="select">
<key>
<column name="base_id" />
</key>
<one-to-many class="com.mappings.Child" />
</set>
</class>
</hibernate-mapping>
Child.java
public class Child implements java.io.Serializable {
private Integer id;
private Base base;
private String name;
//getters and setters
}
Child.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Sep 2, 2014 5:23:25 AM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.mappings.Child" table="child" catalog="testdatabase12">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<many-to-one name="base" class="com.mappings.Base" fetch="select">
<column name="base_id" />
</many-to-one>
<property name="name" type="string">
<column name="name" length="20" />
</property>
</class>
</hibernate-mapping>
I think it's about List. You can use ArrayList for make JSON from List.
Try this code i am not sure but when you clear red marks it will work.
public class App {
public static void main(String[] args) {
SessionFactory sf = HibernateUtil.getSessionFactory();
Session session = sf.openSession();
List names = session.createCriteria(Child.class).list();
GsonBuilder b = new GsonBuilder();
b.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY);
Gson gson = new Gson();
//seperate adding
gson.toJson("propertyName" , List.get(0).getter...());
gson.toJson("propertyName" , List.get(1).getter...());
session.close();
}
}

Hibernate query to get records from three related tables

I have three objects USER, CONTACT and ACTION.
Each USER has many CONTACTS and each CONTACT has many ACTIONS
Each CONTACT and ACTION has status assigned to them, e.g. 20 or 60 or...
Please have a look at the data model.
Requirement is to get the CONTACTs having a particular status, or get the CONTACTs whose ACTIONs have that particular status.
E.g. get me CONTACTs with status 20, or CONTACTs who’s ACTIONs have status 20
At the moment I have the following query that is retrieving the CONTACTs with the status 20 and does not considers that status of the ACTIONs
USER
public class User {
private Integer userID;
private String userFirstName;
private String userLastName;
private Set<Contact> contactSet = new HashSet<Contact>();
private Set<Action> actionSet = new HashSet<Action>();
private ContactCriteria contactCriteria;
.
.
.
}
CONTACT
public class Contact implements Serializable {
private Integer contactID;
private Integer contactStatus = 0;
private String givenName;
private String familyName;
private String streetAddress;
private Set<User> userSet = new HashSet<User>();
private Set<Action> actionSet = new HashSet<Action>();
.
.
.
}
ACTION
public class Action implements Serializable {
private Integer actionID;
private Integer actionStatus;
private User user;
private String actionNote;
private Contact contact;
.
.
.
}
Following are my mapping files:
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smallworks.model" schema="smallworksdb">
<class name="User" table="USERACCOUNT">
<id column="USER_ID" length="500" name="userID">
<generator class="increment"/>
</id>
<property column="USER_FIRSTNAME" generated="never" lazy="false" length="100" name="userFirstName"/>
<property column="USER_LASTNAME" generated="never" lazy="false" length="100" name="userLastName"/>
<set cascade="all" fetch="select" lazy="true" name="contactSet" sort="unsorted" table="USER_CONTACT">
<key column="USER_ID"/>
<many-to-many class="com.smallworks.model.Contact"
column="CONTACT_ID" order-by="CONTACT_ID" unique="false"/>
</set>
<!-- one to many mapping with Action -->
<set inverse="true" lazy="true" name="actionSet" sort="unsorted" order-by="ACTION_DUE_DATE" cascade="save-update">
<key column="USER_ID"/>
<one-to-many class="com.smallworks.model.Action"/>
</set>
<!-- one to one mapping with ContactCriteria -->
<one-to-one name="contactCriteria" class="com.smallworks.model.ContactCriteria"
cascade="save-update" lazy="false"></one-to-one>
</class>
</hibernate-mapping>
Contact.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smallworks.model" schema="smallworksdb">
<class name="Contact" table="CONTACT">
<id column="CONTACT_ID" length="500" name="contactID">
<generator class="increment"/>
</id>
<property column="GIVEN_NAME" generated="never" lazy="false"
length="100" name="givenName"/>
<property column="FAMILY_NAME" generated="never" lazy="false"
length="100" name="familyName"/>
<property column="STREET_ADDRESS" generated="never" lazy="false"
length="100" name="streetAddress"/>
<property column="CONTACT_STATUS" generated="never" lazy="false"
name="contactStatus" type="integer"/>
<set inverse="true" lazy="false" name="userSet" sort="unsorted" table="USER_CONTACT">
<key column="CONTACT_ID"/>
<many-to-many class="com.smallworks.model.User" column="USER_ID" unique="false"/>
</set>
<!-- one to many mapping with Action -->
<set inverse="true" lazy="true" name="actionSet" sort="unsorted" order-by="ACTION_DUE_DATE" cascade="save-update">
<key column="CONTACT_ID"/>
<one-to-many class="com.smallworks.model.Action"/>
</set>
</class>
</hibernate-mapping>
Action.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.smallworks.model" schema="smallworksdb">
<class name="Action" table="ACTION">
<id column="ACTION_ID" length="500" name="actionID">
<generator class="increment"/>
</id>
<property column="ACTION_STATUS" generated="never" lazy="false"
name="actionStatus" type="integer"/>
<!-- many to one mapping with Contact -->
<many-to-one cascade="save-update"
class="com.smallworks.model.Contact" column="CONTACT_ID" lazy="false"
name="contact" not-null="true" />
<!-- many to one mapping with User -->
<many-to-one class="com.smallworks.model.User" column="USER_ID"
lazy="false" name="user" not-null="true"/>
</class>
</hibernate-mapping>
My existing query is:
Query query = session.createQuery("select distinct c FROM com.smallworks.model.User as u INNER JOIN u.contactSet as c WHERE u.userID=:userIDPara AND c.contactStatus in (:contactStatusPara)");
query.setParameter("userIDPara", user.getUserID());
query.setParameterList("contactStatusPara", statusList);
contactList = query.list();
Add an outer join on c.actions as a and an OR restriction on a.status.
select distinct c FROM com.smallworks.model.User as u INNER JOIN u.contactSet as c LEFT OUTER JOIN c.actionSet a WHERE u.userID=:userIDPara AND (c.contactStatus in (:contactStatusPara) OR a.actionStatus in (: actionStatusPara)

Getting Collections using Projection(hibernate)

Employee.java
public class Employee
{
String id;
String name;
List<String> designations;
List<String> qualifications;
}
Employee.hbm.xml
<hibernate-mapping>
<class name="com.novelty.Employee" table="Employee">
<id column="ID" name="id" type="long">
<generator class="increment"/>
</id>
<property column="name" name="name"/>
<list lazy="false" name="designations" table="designations">
<key column="ID"/>
<list-index column="idx"/>
<element column="designation" type="string"/>
</list>
<list lazy="false" name="qualifications" table="qualifications">
<key column="ID"/>
<list-index column="idx"/>
<element column="qualification" type="string"/>
</list>
</hibernate-mapping>
I need to get the list of designation for a particular employee(I have name or id).I don't want to get the Employee object as a whole and get the list. I tried with projections but futile.
Criteria criteria = session.createCriteria(c);
ProjectionList proList = Projections.projectionList();
proList.add(Projections.property("designations"));
criteria.setProjection(proList);
List list = criteria.list();
I got the following exception stack trace.
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
at org.hibernate.loader.criteria.CriteriaLoader.getResultColumnOrRow(CriteriaLoader.java:148)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:639)
at org.hibernate.loader.Loader.doQuery(Loader.java:829)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2533)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
Since designations is a list you should join it
try {
Criteria criteria = session.createCriteria(Employee.class);
criteria.setFetchMode("designations", FetchMode.JOIN);
List list = criteria.list();
} catch (Exception e) {
//print e
}
Getting collections of elements with criteria is not possibile (read here). You have to work with native SQL

Categories