I am struggling with a hibernate problem since hours and can not find any help on any website. I've read dozens of tutorials, tried everything but I always end up with a class cast exception or compilation errors.
My schema in this particular part of the database (mysql innodb) are Plane and Steward. They share a Many2Many relationship.
Using Hibernate Code Generation and Hibernate Tools I generated all POJO classes and the mapping files (including a FlightHasStewardId and FlightHasSteward -> Mapped Composite ID).
I now want to read out all stewards on flight 100!
Notice: Reading other entities works, just M2M reading results in ClassCastEX.
Here my input:
Mapping of FlightHasSteward:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- Generated Jan 1, 2014 1:52:14 PM by Hibernate Tools 4.0.0 -->
<hibernate-mapping>
<class name="FlightHasSteward" table="Flight_has_Steward" catalog="project3flight">
<composite-id name="id" class="FlightHasStewardId">
<key-property name="flightIdflight" type="int">
<column name="Flight_idflight" />
</key-property>
<key-property name="stewardIdsteward" type="int">
<column name="Steward_idsteward" />
</key-property>
</composite-id>
</class>
</hibernate-mapping>
FlightHasSteward.java:
// default package
// Generated Jan 1, 2014 1:52:14 PM by Hibernate Tools 4.0.0
/**
* FlightHasSteward generated by hbm2java
*/
public class FlightHasSteward implements java.io.Serializable {
private FlightHasStewardId id;
public FlightHasSteward() {
}
public FlightHasSteward(FlightHasStewardId id) {
this.id = id;
}
public FlightHasStewardId getId() {
return this.id;
}
public void setId(FlightHasStewardId id) {
this.id = id;
}
}
FlightHasStewardId.java:
// default package
// Generated Jan 1, 2014 1:52:14 PM by Hibernate Tools 4.0.0
/**
* FlightHasStewardId generated by hbm2java
*/
public class FlightHasStewardId implements java.io.Serializable {
private int flightIdflight;
private int stewardIdsteward;
public FlightHasStewardId() {
}
public FlightHasStewardId(int flightIdflight, int stewardIdsteward) {
this.flightIdflight = flightIdflight;
this.stewardIdsteward = stewardIdsteward;
}
public int getFlightIdflight() {
return this.flightIdflight;
}
public void setFlightIdflight(int flightIdflight) {
this.flightIdflight = flightIdflight;
}
public int getStewardIdsteward() {
return this.stewardIdsteward;
}
public void setStewardIdsteward(int stewardIdsteward) {
this.stewardIdsteward = stewardIdsteward;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof FlightHasStewardId))
return false;
FlightHasStewardId castOther = (FlightHasStewardId) other;
return (this.getFlightIdflight() == castOther.getFlightIdflight())
&& (this.getStewardIdsteward() == castOther.getStewardIdsteward());
}
public int hashCode() {
int result = 17;
result = 37 * result + this.getFlightIdflight();
result = 37 * result + this.getStewardIdsteward();
return result;
}
}
Reader.java (my class to read):
/* Method to READ all the stewards on specific flight */
public void getStewards(int flightid) {
Session session = factory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// Query query = session
// .createQuery(" FROM FlightHasSteward as FHS LEFT JOIN FHS.Flight AS F ON F.idFlight = FHS.Flight_idFlight RIGHT JOIN FHS.Steward AS S ON S.idSteward = FHS.Steward_idSteward where FHS.Flight_idFlight = :code");
Query query = session.createQuery(" FROM FlightHasSteward where Flight_idFlight = :code");
query.setParameter("code", flightid);
List<FlightHasStewardId> result = query.list();
final List<FlightHasStewardId> res = (List<FlightHasStewardId>) query.list();
for (final FlightHasStewardId hall_calendar : res) {
System.out.println(hall_calendar.getStewardIdsteward());
}
tx.commit();
} catch (HibernateException e) {
if (tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
And the disturbing output:
Exception in thread "main" java.lang.ClassCastException: FlightHasSteward cannot be cast to FlightHasStewardId
at Reader.getStewards(Reader.java:97)
at Manager.main(Manager.java:24)
I would appreciate any help with this case, thank you all in advance.
You're selecting from FlightHasSteward so the resultant List will contain those types rather than FlightHasStewardId
Query query = session.createQuery(" FROM FlightHasSteward where Flight_idFlight = :code");
query.setParameter("code", flightid);
List<FlightHasSteward> result = query.list();
final List<FlightHasSteward> res = (List<FlightHasSteward>) query.list();
for (final FlightHasSteward steward : res) {
System.out.println(steward.getId().getStewardIdsteward());
}
Related
I'm having a big problem trying to make this little program work
Here are my objects:
Class Country
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Country implements Serializable {
private static final long serialVersionUID = 4947071545454L;
private String countryID;
private String countryName;
private Set<City> cities = new HashSet<City>();
public Country() {
}
public Country(String countryID, String countryName, Set<City> cities) {
this.countryID = countryID;
this.countryName = countryName;
this.cities = cities;
}
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getCountryID() {
return countryID;
}
public void setCountryID(String countryID) {
this.countryID = countryID;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public Set<City> getCities() {
return cities;
}
public void setCities(Set<City> cities) {
this.cities = cities;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Country country = (Country) o;
return countryID != null ? countryID.equals(country.countryID) : country.countryID == null;
}
#Override
public int hashCode() {
return countryID != null ? countryID.hashCode() : 0;
}
public boolean addCity(City c){
return cities.add(c);
}
public boolean removeCity(City c){
return cities.remove(c);
}
}
Class City
import java.io.Serializable;
public class City implements Serializable{
private static final long serialVersionUID = 49470713545454L;
private String cityName;
private Country id;
public City(String cityName, Country id) {
this.cityName = cityName;
this.id = id;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public Country getId() {
return id;
}
public void setId(Country id) {
this.id = id;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
City city = (City) o;
if (cityName != null ? !cityName.equals(city.cityName) : city.cityName != null) return false;
return id != null ? id.equals(city.id) : city.id == null;
}
#Override
public int hashCode() {
int result = cityName != null ? cityName.hashCode() : 0;
result = 31 * result + (id != null ? id.hashCode() : 0);
return result;
}
}
An here are my xml archives:
country.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>
<class name="com.samuel.hibernate.Country" table="country" catalog="training2">
<id name="country" type="string" column="countryID">
<generator class="assign"/>
</id>
<property name="countryName" type="string">
<column name="countryName" length="40" not-null="true" unique="true" />
</property>
<set name="city" inverse="true" cascade="all">
<key column="countryID" not-null="true" />
<one-to-many class="com.samuel.hibernate.City"/>
</set>
</class>
</hibernate-mapping>
city.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>
<class name="com.samuel.hibernate.City" table="city" catalog="training2">
<composite-id name="id">
<key-many-to-one name="countryID" class="com.samuel.hibernate.Country"
column="countryID" />
<key-property name="cityName" column="cityName" type="string"/>
</composite-id>
</class>
</hibernate-mapping>
And here's my main class:
Main class
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
System.out.println("..");
Configuration cfg=new Configuration();
cfg.configure("hibernate.cfg.xml");
// aquí es donde peta si falla conexión con Postgres
//creating seession factory object
System.out.println("Antes de crear sesion");
SessionFactory factory=cfg.buildSessionFactory();
System.out.println("Despues de crear sesion");
//creating session object
Session session=factory.openSession();
//creating transaction object
Transaction t=session.beginTransaction();
Set<City> citiesSpain = new HashSet<>();
Country spain = new Country("es","Spain",citiesSpain);
citiesSpain.add(new City("Barcelona",spain));
citiesSpain.add(new City("Madrid",spain));
session.persist(spain);
t.commit();
session.close();
factory.close();
System.out.println("END");
}
}
When I execute this code I get this error message:
Exception in thread "main" org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.component.PojoComponentTuplizer]
at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:98)
at org.hibernate.tuple.component.ComponentTuplizerFactory.constructDefaultTuplizer(ComponentTuplizerFactory.java:119)
at org.hibernate.tuple.component.ComponentMetamodel.<init>(ComponentMetamodel.java:68)
at org.hibernate.mapping.Component.getType(Component.java:169)
at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:422)
at org.hibernate.mapping.RootClass.validate(RootClass.java:266)
at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:451)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:710)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:726)
at com.samuel.hibernate.Main.main(Main.java:22)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.hibernate.tuple.component.ComponentTuplizerFactory.constructTuplizer(ComponentTuplizerFactory.java:95)
... 10 more
Caused by: org.hibernate.PropertyNotFoundException: Could not locate getter method for property [com.samuel.hibernate.Country#cityName]
at org.hibernate.internal.util.ReflectHelper.findGetterMethod(ReflectHelper.java:418)
at org.hibernate.property.access.internal.PropertyAccessBasicImpl.<init>(PropertyAccessBasicImpl.java:41)
at org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl.buildPropertyAccess(PropertyAccessStrategyBasicImpl.java:27)
at org.hibernate.mapping.Property.getGetter(Property.java:308)
at org.hibernate.tuple.component.PojoComponentTuplizer.buildGetter(PojoComponentTuplizer.java:138)
at org.hibernate.tuple.component.AbstractComponentTuplizer.<init>(AbstractComponentTuplizer.java:47)
at org.hibernate.tuple.component.PojoComponentTuplizer.<init>(PojoComponentTuplizer.java:41)
... 15 more
I've tried looking online but I don't seem to find the solution. In my example, one country can have many cities, but one city can only have on country.
This error means that one or more setters/getters is missing. Make sure you define matching getters/setters for all your properties. And make sure that your properties annotated correctly.
I think that problem is that your cities set name is different in a class and in hbm.xml file. In your entity class you defined set as Set<City> cities and in your XML file you defined this property as name="city". So hibernate is searching setters and getters for city named property.
Make sure that variable and property name coincides. And add empty constructor in City.class.
Hello all I'm new to Hibernate, and so I'm following some tutorials in the internet. But this example gives me the following error.
Any ideas ??
update 1 -
I tried to fix the bug so many times, but still couldn't do it.
When debugging I found that empID is NULL in addEmployee method.
I think that is the reason for this problem.
Sep 24, 2015 4:20:54 PM
org.hibernate.property.access.spi.SetterMethodImpl set ERROR:
HHH000123: IllegalArgumentException in class: Employee, setter method
of property: certificates Sep 24, 2015 4:20:54 PM
org.hibernate.property.access.spi.SetterMethodImpl set ERROR:
HHH000091: Expected type: java.util.SortedMap, actual value:
org.hibernate.collection.internal.PersistentMap
IllegalArgumentException occurred while calling setter for property
[Employee.certificates (expected type = java.util.SortedMap)]; target
= [Employee#3145028a], property value = [{BusinessManagement=Certificate#18bbd9e6,
ComputerScience=Certificate#54de97b9,
ProjectManagement=Certificate#61bb1e36}] at
org.hibernate.property.access.spi.SetterMethodImpl.set(SetterMethodImpl.java:99)
at
org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:607)
at
org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:220)
at
org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4510)
at
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:261)
at
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178)
at
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:109)
at
org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at
org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at
org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at
org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at
org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:678)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:670) at
org.hibernate.internal.SessionImpl.save(SessionImpl.java:665) at
ManageEmployee.addEmployee(ManageEmployee.java:60) at
ManageEmployee.main(ManageEmployee.java:26) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
org.hibernate.property.access.spi.SetterMethodImpl.set(SetterMethodImpl.java:44)
... 21 more Sep 24, 2015 4:20:54 PM
org.hibernate.property.access.spi.SetterMethodImpl set ERROR:
HHH000123: IllegalArgumentException in class: Employee, setter method
of property: certificates Sep 24, 2015 4:20:54 PM
org.hibernate.property.access.spi.SetterMethodImpl set ERROR:
HHH000091: Expected type: java.util.SortedMap, actual value:
org.hibernate.collection.internal.PersistentMap
IllegalArgumentException occurred while calling setter for property
[Employee.certificates (expected type = java.util.SortedMap)]; target
= [Employee#54b00534], property value = [{BusinessManagement=Certificate#3f7e6be2,
ComputerScience=Certificate#4dce2ff}] at
org.hibernate.property.access.spi.SetterMethodImpl.set(SetterMethodImpl.java:99)
at
org.hibernate.tuple.entity.AbstractEntityTuplizer.setPropertyValues(AbstractEntityTuplizer.java:607)
at
org.hibernate.tuple.entity.PojoEntityTuplizer.setPropertyValues(PojoEntityTuplizer.java:220)
at
org.hibernate.persister.entity.AbstractEntityPersister.setPropertyValues(AbstractEntityPersister.java:4510)
at
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:261)
at
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:178)
at
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:109)
at
org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at
org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at
org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at
org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at
org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:678)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:670) at
org.hibernate.internal.SessionImpl.save(SessionImpl.java:665) at
ManageEmployee.addEmployee(ManageEmployee.java:60) at
ManageEmployee.main(ManageEmployee.java:34) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
org.hibernate.property.access.spi.SetterMethodImpl.set(SetterMethodImpl.java:44)
... 21 more Sep 24, 2015 4:20:54 PM
org.hibernate.hql.internal.QueryTranslatorFactoryInitiator
initiateService INFO: HHH000397: Using ASTQueryTranslatorFactory
Exception in thread "main" java.lang.IllegalArgumentException: id to
load is required for loading at
org.hibernate.event.spi.LoadEvent.(LoadEvent.java:92) at
org.hibernate.event.spi.LoadEvent.(LoadEvent.java:62) at
org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2624)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:955) at
ManageEmployee.updateEmployee(ManageEmployee.java:106) at
ManageEmployee.main(ManageEmployee.java:40) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601) at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
RDBMS tables
create table EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
create table CERTIFICATE (
id INT NOT NULL auto_increment,
certificate_type VARCHAR(40) default NULL,
certificate_name VARCHAR(30) default NULL,
employee_id INT default NULL,
PRIMARY KEY (id)
);
POJO Classes
import java.util.*;
public class Employee {
private int id;
private String firstName;
private String lastName;
private int salary;
private SortedMap certificates;
public Employee() {}
public Employee(String fname, String lname, int salary) {
this.firstName = fname;
this.lastName = lname;
this.salary = salary;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName( String first_name ) {
this.firstName = first_name;
}
public String getLastName() {
return lastName;
}
public void setLastName( String last_name ) {
this.lastName = last_name;
}
public int getSalary() {
return salary;
}
public void setSalary( int salary ) {
this.salary = salary;
}
public SortedMap getCertificates() {
return certificates;
}
public void setCertificates( SortedMap certificates ) {
this.certificates = certificates;
}
}
Comparator
import java.util.Comparator;
public class MyClass implements Comparator <String>{
public int compare(String o1, String o2) {
final int BEFORE = -1;
final int AFTER = 1;
/* To reverse the sorting order, multiple by -1 */
if (o2 == null) {
return BEFORE * -1;
}
Comparable thisCertificate = o1;
Comparable thatCertificate = o2;
if(thisCertificate == null) {
return AFTER * 1;
} else if(thatCertificate == null) {
return BEFORE * -1;
} else {
return thisCertificate.compareTo(thatCertificate) * -1;
}
}
}
Certificate Class
public class Certificate implements Comparable <String>{
private int id;
private String name;
public Certificate() {}
public Certificate(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getName() {
return name;
}
public void setName( String name ) {
this.name = name;
}
public int compareTo(String that){
final int BEFORE = -1;
final int AFTER = 1;
if (that == null) {
return BEFORE;
}
Comparable thisCertificate = this;
Comparable thatCertificate = that;
if(thisCertificate == null) {
return AFTER;
} else if(thatCertificate == null) {
return BEFORE;
} else {
return thisCertificate.compareTo(thatCertificate);
}
}
}
Hibernate Mapping File
<?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="Employee" table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<map name="certificates" cascade="all" sort="MyClass">
<key column="employee_id"/>
<index column="certificate_type" type="string"/>
<one-to-many class="Certificate"/>
</map>
<property name="firstName" column="first_name" type="string"/>
<property name="lastName" column="last_name" type="string"/>
<property name="salary" column="salary" type="int"/>
</class>
<class name="Certificate" table="CERTIFICATE">
<meta attribute="class-description">
This class contains the certificate records.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="name" column="certificate_name" type="string"/>
</class>
</hibernate-mapping>
Application Class
import java.util.*;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class ManageEmployee {
private static SessionFactory factory;
public static void main(String[] args) {
try{
factory = new Configuration().configure().buildSessionFactory();
}catch (Throwable ex) {
System.err.println("Failed to create sessionFactory object." + ex);
throw new ExceptionInInitializerError(ex);
}
ManageEmployee ME = new ManageEmployee();
/* Let us have a set of certificates for the first employee */
TreeMap set1 = new TreeMap();
set1.put("ComputerScience", new Certificate("MCA"));
set1.put("BusinessManagement", new Certificate("MBA"));
set1.put("ProjectManagement", new Certificate("PMP"));
/* Add employee records in the database */
Integer empID1 = ME.addEmployee("Manoj", "Kumar", 4000, set1);
/* Another set of certificates for the second employee */
TreeMap set2 = new TreeMap();
set2.put("ComputerScience", new Certificate("MCA"));
set2.put("BusinessManagement", new Certificate("MBA"));
/* Add another employee record in the database */
Integer empID2 = ME.addEmployee("Dilip", "Kumar", 3000, set2);
/* List down all the employees */
ME.listEmployees();
/* Update employee's salary records */
ME.updateEmployee(empID1, 5000);
/* Delete an employee from the database */
ME.deleteEmployee(empID2);
/* List down all the employees */
ME.listEmployees();
}
/* Method to add an employee record in the database */
public Integer addEmployee(String fname, String lname,
int salary, TreeMap cert){
Session session = factory.openSession();
Transaction tx = null;
Integer employeeID = null;
try{
tx = session.beginTransaction();
Employee employee = new Employee(fname, lname, salary);
employee.setCertificates(cert);
employeeID = (Integer) session.save(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
return employeeID;
}
/* Method to list all the employees detail */
public void listEmployees( ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
List employees = session.createQuery("FROM Employee").list();
for (Iterator iterator1 =
employees.iterator(); iterator1.hasNext();){
Employee employee = (Employee) iterator1.next();
System.out.print("First Name: " + employee.getFirstName());
System.out.print(" Last Name: " + employee.getLastName());
System.out.println(" Salary: " + employee.getSalary());
SortedMap<String, Certificate> map =
employee.getCertificates();
for(Map.Entry<String,Certificate> entry : map.entrySet()){
System.out.print("\tCertificate Type: " + entry.getKey());
System.out.println(", Name: " +
(entry.getValue()).getName());
}
}
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to update salary for an employee */
public void updateEmployee(Integer EmployeeID, int salary ){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
employee.setSalary( salary );
session.update(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
/* Method to delete an employee from the records */
public void deleteEmployee(Integer EmployeeID){
Session session = factory.openSession();
Transaction tx = null;
try{
tx = session.beginTransaction();
Employee employee =
(Employee)session.get(Employee.class, EmployeeID);
session.delete(employee);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}finally {
session.close();
}
}
}
It was a problem regarding Hibernate version. You should always make sure that you have taken the correct version of the package.
For this example it should be Hibernate 3x.
I know the above question is very common but I just wanted to know exactly when and How Hibernate is fetching the lazily loaded child records.
below is the sample table structure:
Table Structure:
employee_table(e_id, e_name, e_sal)
(100, XYZ, 20000)
mobile_table(m_id, m_number, e_id)
(1, 8728271817, 100)
(2, 0983813919, 100)
Employee.java
public class Employee implements Serializable {
private static final long serialVersionUID = 1930751473454928876L;
private long employeeId;
private String employeeName;
private double employeeSal;
private Set<Mobile> mobiles;
public long getEmployeeId() {
return employeeId;
}
public void setEmployeeId(long employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public double getEmployeeSal() {
return employeeSal;
}
public void setEmployeeSal(double employeeSal) {
this.employeeSal = employeeSal;
}
public Set<Mobile> getMobiles() {
return mobiles;
}
public void setMobiles(Set<Mobile> mobiles) {
this.mobiles = mobiles;
}
}
Employee.hbm.xml
<hibernate-mapping>
<class name="edu.sandip.hibernate.Employee" table="EMPLOYEE_T">
<id name="employeeId" column="e_id" type="long">
<generator class="increment" />
</id>
<property name="employeeName" column="e_name" type="string" />
<property name="employeeSal" column="e_sal" type="double" />
<set name="mobiles" table="MOBILE_T" inverse="true" lazy="true" fetch="select" >
<key>
<column name="e_id" not-null="true" />
</key>
<one-to-many class="edu.sandip.hibernate.Mobile" />
</set>
</class>
</hibernate-mapping>
Mobile.java
public class Mobile implements Serializable {
private static final long serialVersionUID = 6279006639448045512L;
private long mobId;
private String mobileNumber;
private Employee employee;
public long getMobId() {
return mobId;
}
public void setMobId(long mobId) {
this.mobId = mobId;
}
public String getMobileNumber() {
return mobileNumber;
}
public void setMobileNumber(String mobileNumber) {
this.mobileNumber = mobileNumber;
}
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((mobileNumber == null) ? 0 : mobileNumber.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Mobile other = (Mobile) obj;
if (mobileNumber == null) {
if (other.mobileNumber != null)
return false;
} else if (!mobileNumber.equals(other.mobileNumber))
return false;
return true;
}
}
Mobile.hbm.xml
<hibernate-mapping>
<class name="edu.sandip.hibernate.Mobile" table="MOBILE_T">
<id name="mobId" column="m_id" type="long">
<generator class="increment" />
</id>
<property name="mobileNumber" column="m_number" type="string" />
<many-to-one name="employee" class="edu.sandip.hibernate.Employee" fetch="select">
<column name="e_id" not-null="true" />
</many-to-one>
</class>
</hibernate-mapping>
Below is the code block to fetch the list of employees:
public List<Employee> getAllEmployees() {
List<Employee> list = null;
Session session = null;
try {
session = getSession();
Query query = session.createQuery("FROM Employee");
list = query.list();
for(Employee employee : list) {
System.out.println("Emaployee Name: " + employee.getEmployeeName);
Set<Mobile> mobileSet = employee.getMobiles();
System.out.println("Mobile Numbers: ");
for(Mobile mobile : mobileSet) {
System.out.println(mobile.getMobileNumber());
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(session != null) {
System.out.println("session is still alive");
releaseSession(session);
}
}
return (list);
}
Now, Here the Mobile numbers is the child record of Employee which is been loaded by the Hibernate lazily as per the hibernate configuration in Employee.hbm.xml (lazy = true)
In the above code, after printing the employee name I am printing the mobile numbers of that
employee by iterating the Set mobiles.
I have checked and found that the iteration of the mobileSet is actually fetching the mobileNumbers.
i.e.
for(Mobile mobile : mobileSet) {
System.out.println(mobile.getMobileNumber());
}
SO, How It is happening? Because I am not using any hibernate specific API to fetch the lazily loaded child records. Just Iterating over the set of mobile numbers.
Then how Hibernate is fetching the child records internally? What is the background job that Hibernate is doing while I am iterating over the mobileSet?
Please help in understanding my doubt.
In hibernate lazy loading is triggered whenever a lazy loaded property is accessed and it is still managed by the em. If you would access a lazy loaded property when the entity is detached from the entity manager you would get a org.hibernate.LazyInitializationException
To apply the logic to your example:
mobile.getMobileNumber() will trigger the lazy loading in your code. Hibernate will then automaticly issue a query to the database. This works because hibernate instantiates proxy objects for lazy loaded propertys, once you try to access these proxys hibernate tries to load them in from the database. this will work if the object is managed and this will result in forementioned exception if the entity is detached. There is no need at all to use a hibernate API to trigger the lazy loading it just happens automaticly when a lazy configured property is accessed
In your Employee.hbm.xml file you have stated that the fetch strategy for Mobile is lazy.
That tells hibernate to generate a simple SQL statement to the table that corresponds to Employee without performing any joins with the corresponding Mobile table.
However when employee.getMobiles() is called,
Hibernate will issue a select query to the latter table using a where clause with the primary key of the former table.
The way the fetching is implemented here leads to the infamous N+1 problem
This topic could help you to understand what is the trick behind lazy loading :
How proxy loads the lazy property in Hibernate/JPA
I am new to hibernate and I have stupid problem. My files:
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.PostgreSQLDialect
</property>
<property name="hibernate.connection.driver_class">
org.postgresql.Driver
</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">
jdbc:postgresql://localhost/booktown
</property>
<property name="hibernate.connection.username">
mirek
</property>
<mapping resource="Books.hbm.xml"/>
</session-factory>
</hibernate-configuration>
books.hbm.xml
<?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="Books" table="books">
<meta attribute="Książki w booktown">
This class contains the employee detail.
</meta>
<id name="id" type="int" column="id">
<generator class="native"/>
</id>
<property name="title" column="title" type="string"/>
<property name="author_id" column="author_id" type="int"/>
<property name="subject_id" column="subject_id" type="int"/>
</class>
</hibernate-mapping>
Books.java
public class Books
{
private int id;
private String title;
private int author_id;
private int subject_id;
public Books(String title, int author_id, int subject_id)
{
this.title = title;
this.author_id = author_id;
this.subject_id = subject_id;
}
public void setId(int id)
{
this.id = id;
}
public void setTitle(String title)
{
this.title = title;
}
public void setAuthorId(int author_id)
{
this.author_id = author_id;
}
public void setSubjectId(int subject_id)
{
this.subject_id = subject_id;
}
public int getId()
{
return id;
}
public String getTitle()
{
return title;
}
public int getAuthorId()
{
return author_id;
}
public int getSubjectId()
{
return subject_id;
}
}
and Booktown.java
import java.util.Iterator;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
public class Booktown
{
private static SessionFactory factory;
private static ServiceRegistry serviceRegistry;
public static void main(String[] args)
{
try
{
//private static SessionFactory configureSessionFactory() throws HibernateException {
Configuration configuration = new Configuration();
configuration.configure();
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
factory = configuration.buildSessionFactory(serviceRegistry);
//return factory;
//factory = new Configuration().configure().buildSessionFactory();
}
catch (Throwable ex)
{
System.err.println("Failed to create sessionFactory object." + ex.toString());
throw new ExceptionInInitializerError(ex);
}
Booktown BT = new Booktown();
/* Add few employee records in database */
Integer bID1 = BT.addBook(10, "Jakiś napis", 10, 30);
Integer bID2 = BT.addBook(20, "Jakiś inny napis", 10, 50);
//Integer bID3 = BT.addBook(30, "John", 10000, 14);
/* List down all the employees */
BT.listBooks();
/* Update employee's records */
BT.updateBook(bID1, 5000);
/* Delete an employee from the database */
BT.deleteBook(bID2);
/* List down new list of the employees */
BT.listBooks();
}
/* Method to CREATE a book in the database */
public Integer addBook(int bid, String fname, int lname, int salary)
{
Session session = factory.openSession();
Transaction tx = null;
Integer bID = null;
try
{
tx = session.beginTransaction();
Books book = new Books(fname, lname, salary);
bid = (Integer) session.save(book);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null)
tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
return bID;
}
/* Method to READ all the books */
public void listBooks()
{
Session session = factory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
List<Books> books = session.createQuery("FROM books").list();
for (Iterator<Books> iterator = books.iterator(); iterator.hasNext();)
{
Books book = (Books) iterator.next();
System.out.print("First Name: " + book.getTitle());
System.out.print(" Last Name: " + book.getAuthorId());
System.out.println(" Salary: " + book.getSubjectId());
}
tx.commit();
}
catch (HibernateException e)
{
if (tx != null)
tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
}
/* Method to UPDATE author for a book */
public void updateBook(Integer bID, int auth)
{
Session session = factory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Books book = (Books) session.get(Books.class, bID);
book.setAuthorId(auth);
session.update(book);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null)
tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
}
/* Method to DELETE a book from the records */
public void deleteBook(Integer bID)
{
Session session = factory.openSession();
Transaction tx = null;
try
{
tx = session.beginTransaction();
Books book = (Books) session.get(Books.class, bID);
session.delete(book);
tx.commit();
}
catch (HibernateException e)
{
if (tx != null)
tx.rollback();
e.printStackTrace();
}
finally
{
session.close();
}
}
}
Code is compiling but at run I get:
> paź 15, 2013 8:44:38 PM org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
Failed to create sessionFactory object.org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
Exception in thread "main" java.lang.ExceptionInInitializerError
at Booktown.main(Booktown.java:34)
Caused by: org.hibernate.MappingException: Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:185)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:385)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1790)
at Booktown.main(Booktown.java:25)
Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:138)
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:188)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:341) at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:507)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:146)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163)
... 4 more
Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:135)
... 13 more
Caused by: org.hibernate.PropertyNotFoundException: Could not find a getter for author_id in class Books
at org.hibernate.property.BasicPropertyAccessor.createGetter(BasicPropertyAccessor.java:316)
at org.hibernate.property.BasicPropertyAccessor.getGetter(BasicPropertyAccessor.java:310)
at org.hibernate.mapping.Property.getGetter(Property.java:321)
at org.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertyGetter(PojoEntityTuplizer.java:444)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:200)
at org.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:82)
... 18 more
I found similar problem there was no setter. In my case system says that there is no getter for author_id but it is at line 45 in Books.java.
Could sb tells me what is wrong? Maybe there is an other cause which I don't see...
public int getAuthorId()
{
return author_id;
}
should be (observe, author_id)
public int getAuthor_id()
{
return author_id;
}
OR update XML as #Boris the spider commented.
As far as I know Hibernate requires a no-arg constructor which your Books class does seem to have. So even if you get the save part working I think your code will fail when you attempt to load.
Thus, create a constructor:
public Books(){
}
Why does Hibernate require no argument constructor?
Also, as pointed out previously ditch the XML and use JPA annotations. In line with standard Java conventions rename Books to Book and remove the _ from your variable names.
Alan
I had once this problem and I fix it like that:
You should Generate Constructor, Getters and Setters in NetBeans IDE ( I'm working with IDE is netbeans) so you have to press shortcut ALT+Insert (CTLRL+I on Mac). After invoking the shortcut, all possible generators are offered.
I am using hibernate3 in my java app to access sqlserver 2008 enterprise.
The hibernate mapping uses composite id and when i try to load model it returns null. I spent days to resolve it but still no result. Composite id mapping should be used for multiple field based PK, but in my table no such PK, i wonder why the JBoss Hibernate Tool(eclipse plugin) generated it with composite id mapping ?
I would appreciate any help or comments.
Hibernate Models:
public class AuthorLoginTrack implements java.io.Serializable {
private AuthorLoginTrackId id;
public AuthorLoginTrack() {
}
public AuthorLoginTrack(AuthorLoginTrackId id) {
this.id = id;
}
public AuthorLoginTrackId getId() {
return this.id;
}
public void setId(AuthorLoginTrackId id) {
this.id = id;
}
}
public class AuthorLoginTrackId implements java.io.Serializable {
private long id;
private String userId;
private Date dateCreated;
public AuthorLoginTrackId() {
}
public AuthorLoginTrackId(long id, String userId) {
this.id = id;
this.userId = userId;
}
public AuthorLoginTrackId(long id, String userId, Date dateCreated) {
this.id = id;
this.userId = userId;
this.dateCreated = dateCreated;
}
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
public String getUserId() {
return this.userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Date getDateCreated() {
return this.dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public boolean equals(Object other) {
if ((this == other))
return true;
if ((other == null))
return false;
if (!(other instanceof AuthorLoginTrackId))
return false;
AuthorLoginTrackId castOther = (AuthorLoginTrackId) other;
return (this.getId() == castOther.getId())
&& ((this.getUserId() == castOther.getUserId()) || (this
.getUserId() != null
&& castOther.getUserId() != null && this.getUserId()
.equals(castOther.getUserId())))
&& ((this.getDateCreated() == castOther.getDateCreated()) || (this
.getDateCreated() != null
&& castOther.getDateCreated() != null && this
.getDateCreated().equals(castOther.getDateCreated())));
}
public int hashCode() {
int result = 17;
result = 37 * result + (int) this.getId();
result = 37 * result
+ (getUserId() == null ? 0 : this.getUserId().hashCode());
result = 37
* result
+ (getDateCreated() == null ? 0 : this.getDateCreated()
.hashCode());
return result;
}
}
Hibernate Mapping:
<?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 Apr 6, 2010 4:17:46 PM by Hibernate Tools 3.3.0.GA -->
<hibernate-mapping>
<class name="com.entity.model.AuthorLoginTrack" table="AuthorLoginTrack" schema="dbo" catalog="tribetoyota_db">
<composite-id name="id" class="com.entity.model.AuthorLoginTrackId">
<key-property name="id" type="long">
<column name="ID" precision="18" scale="0" />
</key-property>
<key-property name="userId" type="string">
<column name="UserID" length="20" />
</key-property>
<key-property name="dateCreated" type="timestamp">
<column name="DateCreated" length="16" />
</key-property>
</composite-id>
</class>
</hibernate-mapping>
Table Dump:
/****** Object: Table [dbo].[AuthorLoginTrack] Script Date: 04/14/2010 20:43:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[AuthorLoginTrack](
[ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[UserID] [varchar](20) NOT NULL,
[DateCreated] [smalldatetime] NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[AuthorLoginTrack] ADD CONSTRAINT [DF_AuthorLoginTrack_DateCreated] DEFAULT (getdate()) FOR [DateCreated]
GO
Table:
ID UserID DateCreated
------------------------------------
5 cooler 2005-03-17 18:56:00
6 miumiu 2005-03-17 19:46:00
DAO Code:
AuthorLoginTrack track;
AuthorLoginTrackId trackId;
trackId = new AuthorLoginTrackId();
trackId.setId(5);
track = (AuthorLoginTrack)getSession().load(AuthorLoginTrack.class, trackId);
return track.getId().getUserId(); // returns null why ?:((
Session.load(...) assumes that there's indeed an instance with the given id, most of the time it will return a proxy object without hitting the database. What you're really querying is an instance with id 5, userId = null and date == null.
Basically you're getting an unitialized proxy with a copy of the composite id you used to query it. If the instance really exists you'll be fine, otherwise you'll get an ObjectNotFoundException the first time you'll try to use the object.