-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: Problems with Persisting Object Relational Mappings
PostPosted: Fri Jan 19, 2007 5:29 pm 
Beginner
Beginner

Joined: Wed Oct 25, 2006 12:10 pm
Posts: 41
Hibernate version: 3.1.2

Mapping documents:
<?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="test.DeviceType" table="DEVICE_TYPE">
<id name="id" column="ID" unsaved-value="0" >
<generator class="increment"/>
</id>

<property name="deviceType">
<column name="NAME" />
</property>

<property name="description">
<column name="DESC" />
</property>

<set name="roles" table="DEVICETYPE_ROLES" inverse="true" cascade="all">
<key column="DEVICETYPE_ID" />
<many-to-many column="ROLE_ID" class="test.Role"/>
</set>

</class>

<class name="test.Role" table="ROLE">
<id name="id" column="ID">
<generator class="assigned">
</generator>
</id>

<property name="name" column="NAME" />

</class>



</hibernate-mapping>




Code between sessionFactory.openSession() and session.close():
package test;

import java.util.List;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.dao.DataAccessException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.springframework.dao.DataAccessException;
import org.hibernate.HibernateException;



public class DeviceDao {

private HibernateTemplate hibernateTemplate;
protected final Log logger = LogFactory.getLog(getClass());

public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
logger.info(" *** In setHibernateTemplate method *** ");
this.hibernateTemplate = hibernateTemplate;
}
public void persist(DeviceType dt) {
logger.info(" *** In persist method *** ");
System.out.println(" *** In persist method *** ");
// System.out.println("***ID="+dt.getId()+"***DeviceType="+dt.getDeviceType()+"***Desc="+dt.getDescription());
// hibernateTemplate.save(dt);
System.out.println("***ID="+dt.getId()+"***DeviceType="+dt.getDeviceType()+"***Desc="+dt.getDescription()+"***Role Size="+dt.getRoles().size());
hibernateTemplate.save(dt);
System.out.println("ID***="+dt.getId());
}
public void update(DeviceType instance) {
hibernateTemplate.update(instance);
}
public void remove(Long deviceTypeId) {
Object device = hibernateTemplate.load(DeviceType.class, deviceTypeId);
hibernateTemplate.delete(device);
}



public List getDeviceTypes() throws DataAccessException {

return (List) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session) throws HibernateException {
String sql = "select dt.id, dt.deviceType from DeviceType dt";
Query query = session.createQuery(sql);
return query.list();
}
});

}

public DeviceType getDeviceType(Long id) {
System.out.println("***In DeviceDao selectedDevice***"+id);
DeviceType dt = (DeviceType) hibernateTemplate.get(DeviceType.class, id);
if (dt == null) {
throw new ObjectRetrievalFailureException(DeviceType.class, id);
}
return dt;
}

}




Full stack trace of any exception that occurs:
2007-01-19 12:14:03,759 ERROR [org.hibernate.property.BasicPropertyAccessor] - <IllegalArgumentException in class: test.Role, getter method of property: id>
2007-01-19 12:14:03,759 WARN [test.TestBean] - <IllegalArgumentException occurred calling getter of test.Role.id; nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of test.Role.id>



Name and version of the database you are using:
HSQLDB


The generated SQL (show_sql=true):
Expected to generate following SQL statements but it doesn't due to Error
insert into DeviceType_Roles(DeviceType_id, Tole_Id) values (?, ?)
insert into Device_Type(Id, Name, Desc) values(?,?,?)



Debug level Hibernate log excerpt:
2007-01-19 12:14:03,759 ERROR [org.hibernate.property.BasicPropertyAccessor] - <IllegalArgumentException in class: test.Role, getter method of property: id>
2007-01-19 12:14:03,759 WARN [test.TestBean] - <IllegalArgumentException occurred calling getter of test.Role.id; nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of test.Role.id>





Problems with Session and transaction handling?
Nope

Scenario :
Its an example of Many-To-Many Object Relationship i.e. DeviceType object is associated with Roles object. Here is the snippet
DeviceType dt = new DeviceType();
dt.setDeviceType(deviceType);
dt.setDescription(description);
dt.setRoles(deviceRoles);
deviceDao.persist(dt); // In Business Layer
Please not deviceRoles is Set of Roles.
deviceDao.persist(dt); results in call to Hibernate Layer and executes hibernateTemplate.save(dt);

Expected Results:
To persist DeviceType object along with set of Roles into DeviceType table and DeviceType_Roles table as shown below
insert into DeviceType_Roles(DeviceType_id, Tole_Id) values (?, ?)
insert into Device_Type(Id, Name, Desc) values(?,?,?)

Observed Results:
IllegalArgumentException occurred calling getter method of property: id>

Any pointers/suggestions will be highly appreciated

Regards
Bansi


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 7:58 pm 
Beginner
Beginner

Joined: Tue May 23, 2006 4:10 pm
Posts: 38
Location: Charleston, SC
Okay, you caught me on a good day. It looks like your id properties are Long so you need to add the type attribute on the <id> tag and set it to "long".

<id name="id" column="ID" type="long" unsaved-value="0" >
<generator class="increment"/>
</id>

<id name="id" column="ID" type="long">
<generator class="assigned">
</generator>

Always set the type attribute on all property mappings! If the data type of the ID properties is not Long in your POJOs, change the type to "integer" instead. Your problem has nothing to do with the code you posted. You should of posted your POJO source, not the DAO code.

Grant


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 8:15 pm 
Beginner
Beginner

Joined: Wed Oct 25, 2006 12:10 pm
Posts: 41
Here are the POJOs

package test;

import java.util.Set;

public class DeviceType {
private Long id;
private String deviceType;
private String description;
private Set roles;

public DeviceType(){

}

public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

public Set getRoles() {
return roles;
}

public void setRoles(Set roles) {
this.roles = roles;
}


}




package test;

public class Role {
private Long id;
private String name;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}


}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 8:21 pm 
Beginner
Beginner

Joined: Wed Oct 25, 2006 12:10 pm
Posts: 41
Hi Grant
I tried type="long" in the mapping file it still doesn't work

Regards
Bansi


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 19, 2007 8:26 pm 
Beginner
Beginner

Joined: Tue May 23, 2006 4:10 pm
Posts: 38
Location: Charleston, SC
Did the exception occur in the same place or on a different property? You have several property mappings that don't have a type attribute. If it occurred in the same place then I'm not sure. I'd have to debug your code to really figure it out. You might also post your table definitions so we can all look at them too.

Bansi, based on your posts, I'd refactor your hibernate mapping to mirror what I've included in my post. I can't promise it will fix your problem but give it a try anyway.

Grant

Code:
<?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="test">
  <class name="DeviceType" table="DEVICE_TYPE">
    <id name="id" column="ID" type="long">
      <generator class="increment"/>
    </id>

    <property name="deviceType" column="NAME" type="string"/>
    <property name="description" column="DESC" type="string"/>

    <set name="roles" table="DEVICETYPE_ROLES" cascade="all">
      <key column="DEVICETYPE_ID" />
      <many-to-many column="ROLE_ID" class="Role"/>
    </set>
  </class>

  <class name="Role" table="ROLE">
    <id name="id" column="ID" type="long">
      <generator class="assigned"/>
    </id>

    <property name="name" column="NAME" type="string"/>
  </class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 22, 2007 12:33 am 
Beginner
Beginner

Joined: Wed Oct 25, 2006 12:10 pm
Posts: 41
Hi Grant
Thanks for your time
The exception do occured on the same property i.e. id property of Role

Here is the Debug generated using Log4J

Debug level Hibernate log excerpt:

2007-01-19 12:14:03,759 ERROR [org.hibernate.property.BasicPropertyAccessor] - <IllegalArgumentException in class: test.Role, getter method of property: id>
2007-01-19 12:14:03,759 WARN [test.TestBean] - <IllegalArgumentException occurred calling getter of test.Role.id; nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of test.Role.id>

Here are the table definations

create table "DEVICE_TYPE"(
"ID" INTEGER not null,
"NAME" VARCHAR(20) not null,
"DESC" VARCHAR(50),
constraint "SYS_PK_DEVICE_TYPE" primary key ("ID")
);

create unique index "SYS_PK_DEVICE_TYPE" on "DEVICE_TYPE"("ID");




create table "ROLE"(
"ID" INTEGER not null,
"NAME" VARCHAR(50) not null,
constraint "SYS_PK_ROLE" primary key ("ID")
);

create unique index "SYS_PK_ROLE" on "ROLE"("ID");



Many-To-Many Intermediate Table


create table "DEVICETYPE_ROLES"(
"DEVICETYPE_ID" INTEGER not null,
"ROLE_ID" INTEGER not null,
constraint "SYS_PK_DEVICETYPE_ROLES" primary key ("DEVICETYPE_ID","ROLE_ID")
);

alter table "DEVICETYPE_ROLES"
add constraint "SYS_FK_22"
foreign key ("DEVICETYPE_ID")
references "DEVICE_TYPE"("ID");
alter table "DEVICETYPE_ROLES"
add constraint "SYS_FK_23"
foreign key ("ROLE_ID")
references "ROLE"("ID");
create unique index "SYS_PK_DEVICETYPE_ROLES" on "DEVICETYPE_ROLES"("DEVICETYPE_ID","ROLE_ID");
create index "SYS_IDX_24" on "DEVICETYPE_ROLES"("DEVICETYPE_ID");
create index "SYS_IDX_26" on "DEVICETYPE_ROLES"("ROLE_ID");


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 22, 2007 1:00 am 
Beginner
Beginner

Joined: Wed Oct 25, 2006 12:10 pm
Posts: 41
I have observed the following wierd problems

1) On Refresh the record gets inserted only into DeviceType

Here is the Debug Level Log generated using log4J

*** In persist method ***
***ID=null***DeviceType=switch***Desc=switch***Role Size=0
2007-01-21 20:43:06,437 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - <Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]>
2007-01-21 20:43:06,453 INFO [org.springframework.jdbc.support.SQLErrorCodesFactory] - <SQLErrorCodes loaded: [DB2, HSQL, MS-SQL, MySQL, Oracle, Informix, PostgreSQL, Sybase]>
Hibernate: select max(ID) from DEVICE_TYPE
Hibernate: insert into DEVICE_TYPE (NAME, DESC, ID) values (?, ?, ?)

The missing thing here is it doesnt insert into intermediate table i.e
insert into DEVICETYPE_ROLES(DEVICETYPE_ID, ROLE_ID) values(?,?)


2) Here is the DAOHibernateImpl code i.e. DeviceDao.java
package test;

import java.util.List;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.dao.DataAccessException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.springframework.dao.DataAccessException;
import org.hibernate.HibernateException;



public class DeviceDao {

private HibernateTemplate hibernateTemplate;
protected final Log logger = LogFactory.getLog(getClass());

public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
logger.info(" *** In setHibernateTemplate method *** ");
this.hibernateTemplate = hibernateTemplate;
}
public void persist(DeviceType dt) {
logger.info(" *** In persist method *** ");
System.out.println(" *** In persist method *** ");
// System.out.println("***ID="+dt.getId()+"***DeviceType="+dt.getDeviceType()+"***Desc="+dt.getDescription());
// hibernateTemplate.save(dt);
System.out.println("***ID="+dt.getId()+"***DeviceType="+dt.getDeviceType()+"***Desc="+dt.getDescription()+"***Role Size="+dt.getRoles().size());
hibernateTemplate.save(dt);
System.out.println("ID***="+dt.getId());
}
}

The wierds things:
1) Insertion happens only on Refresh and that too only in DeviceType table and not in intermediate table . Is it due to Backing Bean set in the session scope in application-config.xml.

2) Insertion on first time i.e. click on Submit button results in following error

*** In persist method ***
***ID=null***DeviceType=server***Desc=server***Role Size=3
2007-01-21 20:53:26,796 ERROR [org.hibernate.property.BasicPropertyAccessor] - <IllegalArgumentException in class: test.Role, getter method of property: id>
2007-01-21 20:53:26,796 WARN [test.TestBean] - <IllegalArgumentException occurred calling getter of test.Role.id; nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of test.Role.id>

From the above log it can be deduce that in the DAOHibernateImpl class i.e. DeviceDAO.java the code throws exception at the save method i.e.

hibernateTemplate.save(dt);

So is it that save method doesnt persist object data into two tables if object DeviceType is associated with set of Roles

I hope i would get an answer for this basic question from Hibernate Forum

Regards
Bansi


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 22, 2007 11:08 am 
Beginner
Beginner

Joined: Tue May 23, 2006 4:10 pm
Posts: 38
Location: Charleston, SC
Bansi,

I honestly don't see anything wrong with your mapping files or your database schema. You are using Spring, a framework for which I have no personal experience. I prefer the new Seam framework to Spring so I wouldn't be much help with a Spring issue. The only guidance I can offer is verify your mappings and POJOs using a junit test. We maintain 3 or 4 different hibernate config files in our application for this exact reason: testing the persistence outside the application context.

Grant


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.