Composite key with one to many hibernate - java

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.

Related

session.save() have some mistake with "unknown entity "

I'm new to hibernate and as I researched. When i want to start my JUnit, this mistake could be occur every time. I guess something wrong with my hbm.xml file. Maybe I am missing something because I'm still new to hibernate.
This is my hbm.xml file.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.test.UserEntity" table="user" schema="" catalog="junwa">
<id name="id" column="id"/>
<property name="username" column="username"/>
<property name="gender" column="gender"/>
<property name="birthday" column="birthday"/>
<property name="addres" column="addres"/>
</class>
</hibernate-mapping>
And this is my UserEntity.java file
package com.test;
import javax.persistence.*;
import java.sql.Timestamp;
#Entity
#Table(name = "user", schema = "", catalog = "junwa")
public class UserEntity {
private int id;
private String username;
private String gender;
private Timestamp birthday;
private String addres;
#Id
#Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#Basic
#Column(name = "username")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Basic
#Column(name = "gender")
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
#Basic
#Column(name = "birthday")
public Timestamp getBirthday() {
return birthday;
}
public void setBirthday(Timestamp birthday) {
this.birthday = birthday;
}
#Basic
#Column(name = "addres")
public String getAddres() {
return addres;
}
public void setAddres(String addres) {
this.addres = addres;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserEntity that = (UserEntity) o;
if (id != that.id) return false;
if (username != null ? !username.equals(that.username) : that.username != null) return false;
if (gender != null ? !gender.equals(that.gender) : that.gender != null) return false;
if (birthday != null ? !birthday.equals(that.birthday) : that.birthday != null) return false;
if (addres != null ? !addres.equals(that.addres) : that.addres != null) return false;
return true;
}
#Override
public int hashCode() {
int result = id;
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (gender != null ? gender.hashCode() : 0);
result = 31 * result + (birthday != null ? birthday.hashCode() : 0);
result = 31 * result + (addres != null ? addres.hashCode() : 0);
return result;
}
}
This is my test file.
/**
* Created by junwa on 2017/4/2.
*/
import com.test.Students;
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;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
public class StudentsTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
#Before
public void init(){
// create a deploy object
Configuration config = new Configuration().configure();
// create a service licenced object
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
// create a session factory object
sessionFactory = config.buildSessionFactory(serviceRegistry);
// create a sessoin object
session = sessionFactory.openSession();
// start transaction
transaction = session.beginTransaction();
}
#After
public void destroy(){
// commit transaction
transaction.commit();
// close session
session.close();
// close session factory
sessionFactory.close();
}
#Test
public void testSaveStudents(){
// create a object
Students s = new Students(1,"junwa","male",new Date(),"Anhui");
// save object to mysql database
session.save(s);
session.flush();
}
}
This my output
enter image description here
As Faraz Durrani said when you already have done the mapping in hbm.xml file, why do you need annotations for? Or the vice versa.You have to remove one of them. I would say remove hbm.xml file and use Annotations only.
One more thing I have noticed that you are not closing the transection also.
You can't use hbm.xml and annotation at the same time.

hibernate dynamic component equivalent annotation

What is the equivalent way of defining dynamic component in hibernate by annotations?
public abstract class CustomizableEntity {
private Map customProperties;
public Map getCustomProperties() {
if (customProperties == null)
customProperties = new HashMap();
return customProperties;
}
public void setCustomProperties(Map customProperties) {
this.customProperties = customProperties;
}
public Object getValueOfCustomField(String name) {
return getCustomProperties().get(name);
}
public void setValueOfCustomField(String name, Object value) {
getCustomProperties().put(name, value);
}
}
my entity:
public class Contact extends CustomizableEntity {
private int id;
private String 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;
}
}
hibernate xml:
<hibernate-mapping auto-import="true" default-access="property" default-cascade="none" default-lazy="true">
<class abstract="false" name="com.enterra.customfieldsdemo.domain.Contact" table="tbl_contact">
<id column="fld_id" name="id">
<generator class="native"/>
</id>
<property name="name" column="fld_name" type="string"/>
<dynamic-component insert="true" name="customProperties" optimistic-lock="true" unique="false" update="true">
</dynamic-component>
</class>
</hibernate-mapping>
I want to use a dynamic-component by HashMap to create entities at runtime.
What is the equivalent way of defining dynamic component in hibernate by annotations?
http://www.infoq.com/articles/hibernate-custom-fields

Mapping CHAR(0) in MySQL to boolean in Hibernate

I have a table named refund_rule in mysql(version 5.5). Here is it's definition:
CREATE TABLE `refund_rule` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`PERCENTAGE` char(0) DEFAULT NULL COMMENT 'BOOLEAN shortcut.NULL<=>false,EMPTY<=>true',
`DEDUCTION_AMOUNT` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`ID`)
);
The corresponding class in Hibernate(version 3.2) is named RefundRule. The HBM file looks like this:
<?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="hibernatesample.dao.RefundRule" table="refund_rule" catalog="back_end_proc">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="percentage" type="string">
<column name="PERCENTAGE" length="0">
<comment>BOOLEAN shortcut.NULL<=>false,EMPTY<=>true</comment>
</column>
</property>
<property name="deductionAmount" type="java.lang.Integer">
<column name="DEDUCTION_AMOUNT" />
</property>
</class>
</hibernate-mapping>
The class generated by the wizard in NetBeans(version 7.0) was this:
public class RefundRule implements java.io.Serializable {
private Integer id;
private String percentage;
private Integer deductionAmount;
public CancellationRule() {
}
public CancellationRule(String percentage, Integer deductionAmount) {
this.percentage = percentage;
this.deductionAmount = deductionAmount;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPercentage() {
return this.percentage;
}
public void setPercentage(String percentage) {
this.percentage = percentage;
}
public Integer getDeductionAmount() {
return this.deductionAmount;
}
public void setDeductionAmount(Integer deductionAmount) {
this.deductionAmount = deductionAmount;
}
}
I added 2 more methods in it setPercentage(boolean) & isPercentage(), and changed the method setPercentage(String) , so that i can use that String object as boolean in my Java(version 1.6) program.
public class RefundRule implements java.io.Serializable {
.
.
.
public String getPercentage() {
return this.percentage;
}
public void setPercentage(String percentage) {
this.percentage = percentage==null?null:"";
}
.
.
.
public void setPercentage(boolean percentage){
setPercentage(percentage?"":null);
}
public boolean isPercentage(){
return percentage!=null;
}
}
My Question is:
Is there any way that I can keep only two methods: setPercentage(boolean) and isPercentage() , and map the boolean percentage variable to PERCENTAGE CHAR(0) variable in mysql.
===================================================================
EDIT added on 2013-11-23
Following the answer by #GreyBeardedGeek , I made following changes in code:
(Changes in brief)
Added Class CharToBoolUserType
Changed the type-attribute of hbm-element: percentage in RefundRule.hbm.xml
(Code related to above mentioned changes)
The class CharToBoolUserType:
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
public class CharToBoolUserType implements UserType {
private static final int[] SQL_TYPES = {Types.CHAR};
#Override
public Object assemble(Serializable serializable, Object object) throws HibernateException {
return serializable;
}
#Override
public Object deepCopy(Object object) throws HibernateException {
return object;
}
#Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
#Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
} else if (x == null || y == null) {
return false;
} else {
return x.equals(y);
}
}
#Override
public boolean isMutable() {
return false;
}
#Override
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
return resultSet.getObject(names[0]) != null;
}
#Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
preparedStatement.setObject(index, ((Boolean) value).booleanValue() ? "" : null);
}
#Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
#Override
public Class returnedClass() {
return boolean.class;
}
#Override
public int[] sqlTypes() {
return SQL_TYPES;
}
#Override
public int hashCode(Object object) throws HibernateException {
if (object == null) {
return 0;
}
// is `object` a String ? Or boolean?
return 1;
}
}
The file RefundRule.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="hibernatesample.dao.RefundRule" table="refund_rule" catalog="back_end_proc">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="identity" />
</id>
<property name="percentage" type="hibernatesample.dao.CharToBoolUserType">
<column name="PERCENTAGE" length="0">
<comment>BOOLEAN shortcut.NULL<=>false,EMPTY<=>true</comment>
</column>
</property>
<property name="deductionAmount" type="java.lang.Integer">
<column name="DEDUCTION_AMOUNT" />
</property>
</class>
</hibernate-mapping>
Since I want the code of the class CharToBoolUserType to be complete in all sense, I have following questions:
1. What is the class of object in hashCode(Object object), Boolean or String? Who calls this method?
2. What the method public Object replace(Object original, Object target, Object owner) supposed to do? replace original with target and set/put it in owner. In this case: is original of String type, target of Boolean type, and owner of RefundRule type ?
Any suggestion(s) to improve this code is welcome.
=================================================
Just for reference, the class RefundRule is like this now:
public class RefundRule implements java.io.Serializable {
private Integer id;
private boolean percentage;
private Integer deductionAmount;
public RefundRule() {
}
public RefundRule(boolean percentage, Integer deductionAmount) {
this.percentage = percentage;
this.deductionAmount = deductionAmount;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getDeductionAmount() {
return this.deductionAmount;
}
public void setDeductionAmount(Integer deductionAmount) {
this.deductionAmount = deductionAmount;
}
public void setPercentage(boolean percentage){
this.percentage=percentage;
}
public boolean isPercentage(){
return percentage;
}
}
I believe that you are looking for Hibernate's UserType, which allows you to provide a custom type mapping.
See, for example, http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/types.html#types-custom

Why am I getting org.hibernate.PropertyAccessException?

While trying to run the following program :
public class Runner {
public static void main(String args[]) {
Configuration config = new Configuration().configure();
SessionFactory sessFact = config.buildSessionFactory();
Session sess = sessFact.openSession();
Transaction trans = sess.beginTransaction();
Person p = new Person();
p.setPersonName("Suhail");
Set<String> set = new HashSet<String>();
set.add("Address-1");
set.add("Address-2");
set.add("Address-3");
p.setAddressSet(set);
sess.save(p);
trans.commit();
}
}
I am getting :
SEVERE: IllegalArgumentException in class: pojo.Address, getter method
of property: addressID
Exception in thread "main" org.hibernate.PropertyAccessException:
IllegalArgumentException occurred calling getter of pojo.Address.addressID
I don't know the reason for this. I am trying to make one to many association between Person and Address class.
mapping xml:
<hibernate-mapping>
<class name="pojo.Person" table="person">
<id name="personID" column="p_id">
<generator class="increment" />
</id>
<property name="personName" column="p_name" />
<set name="addressSet" table="address" cascade="all">
<key column="p_id" />
<one-to-many class="pojo.Address" />
</set>
</class>
<class name="pojo.Address" table="address">
<id name="addressID" column="a_id">
<generator class="increment" />
</id>
<property name="personAddress" column="p_address" />
</class>
</hibernate-mapping>
POJO:
Person
public class Person {
private int personID;
private String personName;
private Set addressSet;
public int getPersonID() {
return personID;
}
public void setPersonID(int personID) {
this.personID = personID;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public Set getAddressSet() {
return addressSet;
}
public void setAddressSet(Set addressSet) {
this.addressSet = addressSet;
}
}
Address
public class Address {
private int addressID;
private String personAddress;
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
public String getPersonAddress() {
return personAddress;
}
public void setPersonAddress(String personAddress) {
this.personAddress = personAddress;
}
}
SQL that created table
CREATE TABLE person(p_id INTEGER,p_name TEXT,PRIMARY KEY(p_id));
CREATE TABLE address(a_id INTEGER,p_address TEXT);
In your example you add to adress set Strings. But in your configuration you specify Address class.So I think your problem in this lines:
Set<String> set = new HashSet<String>();
set.add("Address-1");
set.add("Address-2");
set.add("Address-3");
You need to change set to Set<Address> and add Address objects in set:
Set<Address> set = new HashSet<>();
Address address = new Address();
address.setPersonAddress("Address-1");
set.add(address);
You can do couple of things without Mapping xml file. Place #Embeddable on ur Pojo of
#Embeddable
#Entity
public class Address {
#Id
private int addressID;
private String personAddress;
public int getAddressID() {
return addressID;
}
public void setAddressID(int addressID) {
this.addressID = addressID;
}
public String getPersonAddress() {
return personAddress;
}
public void setPersonAddress(String personAddress) {
this.personAddress = personAddress;
}
}
Then on
public class Runner {
public static void main(String args[]) {
Configuration config = new Configuration().configure();
SessionFactory sessFact = config.buildSessionFactory();
Session sess = sessFact.openSession();
Transaction trans = sess.beginTransaction();
Person p = new Person();
p.setPersonName("Suhail");
#ElementCollection//To inform hibernate to save this in a seperate table
Set<String> set = new HashSet<String>();
set.add("Address-1");
set.add("Address-2");
set.add("Address-3");
p.setAddressSet(set);
sess.save(p);
trans.commit();
}
}
Better to use Annotations so that we get rid of writing .hbm.xml mapping File

Hibernate mapping issue with composite-id

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.

Categories