Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
3.1.2
I have problem when persisting a user object which contains a set with roles in it when a web form is submitted. I have junit tested the DAO and service layer and even using a MockHttpServletRequest object (from Spring) to test the onSubmit method and it all works OK, but when I submit the form from the web for real, I get the following exception everytime:
Code:
2006-03-04 16:44:58,649 [63733 ] [http-8080-Processor24] INFO org.springframework.beans.factory.xml.XmlBeanDefinitionReader (loadBeanDefinitions) - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2006-03-04 16:44:58,977 [64061 ] [http-8080-Processor24] INFO org.springframework.jdbc.support.SQLErrorCodesFactory (<init>) - SQLErrorCodes loaded: [DB2, HSQL, MS-SQL, MySQL, Oracle, Informix, PostgreSQL, Sybase]
Hibernate: select user0_.USERS_ID as USERS1_, user0_.VERSION as VERSION7_, user0_.USERNAME as USERNAME7_, user0_.PASSWORD as PASSWORD7_, user0_.ENABLED as ENABLED7_, user0_.FIRST_NAME as FIRST6_7_, user0_.LAST_NAME as LAST7_7_, user0_.CREATED as CREATED7_, user0_.MODIFIED as MODIFIED7_, user0_.MODIFIED_BY as MODIFIED10_7_ from USERS user0_ order by user0_.USERNAME
Hibernate: select authoritie0_.USERS_ID as USERS7_1_, authoritie0_.AUTHORITIES_ID as AUTHORIT1_1_, authoritie0_.AUTHORITIES_ID as AUTHORIT1_0_, authoritie0_.VERSION as VERSION8_0_, authoritie0_.AUTHORITY as AUTHORITY8_0_, authoritie0_.CREATED as CREATED8_0_, authoritie0_.MODIFIED as MODIFIED8_0_, authoritie0_.MODIFIED_BY as MODIFIED6_8_0_, authoritie0_.USERS_ID as USERS7_8_0_ from AUTHORITIES authoritie0_ where authoritie0_.USERS_ID=?
2006-03-04 16:44:59,798 [64882 ] [http-8080-Processor24] INFO org.springframework.ui.context.support.ResourceBundleThemeSource (getTheme) - Theme created: name 'theme', basename [theme]
2006-03-04 16:44:59,812 [64896 ] [http-8080-Processor24] INFO org.springframework.web.util.ExpressionEvaluationUtils (<clinit>) - Using JSP 2.0 ExpressionEvaluator
Hibernate: select role0_.ROLE_ID as ROLE1_, role0_.VERSION as VERSION9_, role0_.NAME as NAME9_, role0_.DESCRIPTION as DESCRIPT4_9_, role0_.CREATED as CREATED9_, role0_.MODIFIED as MODIFIED9_, role0_.MODIFIED_BY as MODIFIED7_9_ from ROLE role0_ order by role0_.NAME
Hibernate: select next value for USERS_SEQ from dual_USERS_SEQ
2006-03-04 16:45:15,647 [80731 ] [http-8080-Processor24] ERROR org.hibernate.property.BasicPropertyAccessor (get) - IllegalArgumentException in class: au.com.woolworths.refimpl.domain.AbstractEntity, getter method of property: id
2006-03-04 16:45:15,679 [80763 ] [http-8080-Processor24] ERROR au.com.woolworths.refimpl.dao.hibernate.UserDaoImpl (create) - org.springframework.orm.hibernate3.HibernateSystemException: IllegalArgumentException occurred calling getter of au.com.woolworths.refimpl.domain.AbstractEntity.id; nested exception is org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of au.com.woolworths.refimpl.domain.AbstractEntity.id
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of au.com.woolworths.refimpl.domain.AbstractEntity.id
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:119)
at org.hibernate.tuple.AbstractTuplizer.getIdentifier(AbstractTuplizer.java:103)
Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException@a69b6b
at sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:105)
... 108 more
I logged id when this occurs and it is null, but it doesn't seem to matter when using a junit test to insert the data. The next sequence number is inserted correctly in both the USERS and AUTHORITIES tables.
Mapping documents:For the User class:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Mapping file for the Hibernate implementation of User. -->
<hibernate-mapping auto-import="true" default-lazy="false">
<class name="au.com.woolworths.refimpl.domain.User" table="USERS">
<id name="id" column="USERS_ID" type="long">
<generator class="sequence">
<param name="sequence">USERS_SEQ</param>
</generator>
</id>
<version name="version" column="VERSION" />
<property name="username" column="USERNAME" type="string" />
<property name="password" column="PASSWORD" type="string" />
<property name="enabled" column="ENABLED" type="true_false" />
<property name="firstName" column="FIRST_NAME" type="string" />
<property name="lastName" column="LAST_NAME" type="string" />
<property name="created" column="CREATED" type="timestamp" />
<property name="modified" column="MODIFIED" type="timestamp" />
<property name="modifiedBy" column="MODIFIED_BY" type="string" />
<set name="authorities" inverse="true" cascade="all">
<key column="USERS_ID" />
<one-to-many class="au.com.woolworths.refimpl.domain.Authority" />
</set>
</class>
<query name="findUser">
<![CDATA[from User as user where user.id = ?]]>
</query>
<query name="findUserByUsername">
<![CDATA[from User as user where user.username = ?]]>
</query>
<query name="getUsers">
<![CDATA[from User as user order by user.username]]>
</query>
</hibernate-mapping>
For the Authority class:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Mapping file for the Hibernate implementation of Authority. -->
<hibernate-mapping auto-import="true" default-lazy="false">
<class name="au.com.woolworths.refimpl.domain.Authority" table="AUTHORITIES">
<id name="id" column="AUTHORITIES_ID" type="long">
<generator class="sequence">
<param name="sequence">AUTHORITIES_SEQ</param>
</generator>
</id>
<version name="version" column="VERSION" />
<property name="authority" column="AUTHORITY" type="string" />
<property name="created" column="CREATED" type="timestamp" />
<property name="modified" column="MODIFIED" type="timestamp" />
<property name="modifiedBy" column="MODIFIED_BY" type="string" />
<many-to-one name="user" column="USERS_ID" class="au.com.woolworths.refimpl.domain.User" not-null="true" />
</class>
</hibernate-mapping>
User and Authority extend Entity which in turn extends from AbstractEntity which has common attributes such as id for the primary key (as a Long) for both classes. The getter for id is simply Long getId() returning id.
I select the roles on the web form using a multiple select input box. I can see the paraneters coming through OK in the controller. I'm also using a bidirectional mapping, ie many-to-one from Authority to User and one-to-many from User to Authority, which may be overkill, but it seems to work, at least from any Junit test.
I'm completely baffled by this and would appreciate any help
Thanks
Alan