From: David Ng (JIRA) <no...@at...> - 2006-07-28 20:34:21
|
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1953?page=comments#action_23792 ] David Ng commented on HHH-1953: ------------------------------- I have spoken in detail with Robb Greathouse about this. Our enterprise software engine really needs this to make things work better. Would appreciate your help on this. Thanks, David. > Problem with hibernate proxy object and ClassMetaData > ----------------------------------------------------- > > Key: HHH-1953 > URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1953 > Project: Hibernate3 > Type: Bug > Versions: 3.1.2 > Environment: Tested environment: > - Hibernate 3.1.2 > - Hibernate 3.1.3 > - Postgresql 8.1 > - Jdk 1.5.0_06 > - Windows XP SP2 and Linux > Reporter: David Ng > Priority: Critical > > > Hi, > The problem can be summarised as follow: > - If an hibernate entity object has proxy attribute is defined inside class node of hbm.xml file, ClassMetaData.getPropertyValue() of any property will throw IllegalArgumentException; > - Regardless whether Reflection API is used or hibernate.cglib.use_reflection_optimizer is either set to true or false; > - If the proxy attribute is not defined, ClassMetaData::getPropertyValue() / ClassMetaData::getPropertyValues() returns the values successfully; and > - Accessing the TsRecStat property by invoking TsPassword::getTsRecStat() does not cause exception to be thrown in any of the case. > My question: > - If reflection API should not be used to access the property value, shouldn't hibernate ClassMetaData API be used to access the property value? > 2 postings have been made in regard to this on hibernate forum: > http://forum.hibernate.org/viewtopic.php?t=955828 > http://forum.hibernate.org/viewtopic.php?t=958029 > ======================================================================================================================== > THE TEST CODE: > public void testAccessingTsPasswordProxyWithClassMetaDataAPI() > { > Session currentSession = null; > Transaction transaction = null; > try > { > ClassMetadata passwordClassMetaData = m_sessionFactory.getClassMetadata( TsPassword.class ); > currentSession = m_sessionFactory.openSession(); > transaction = currentSession.beginTransaction(); > Query query = currentSession.createQuery( "FROM TsPassword AS p" ); > Iterator it = query.iterate(); > while( it.hasNext() ) > { > Object obj = it.next(); > ITsPassword itspassword = (ITsPassword) obj; > Date tsExpiryTimestamp = itspassword.getTsExpiryTimestamp(); > passwordClassMetaData.getPropertyValue( itspassword, "TsRecStat", EntityMode.POJO ); > Object expiryFromPasswordInterface = passwordClassMetaData.getPropertyValue( > itspassword, "TsExpiryTimestamp", EntityMode.POJO > ); > assertEquals( "Expiry timestamp from interface", tsExpiryTimestamp, expiryFromPasswordInterface ); > Object propertyValue = passwordClassMetaData.getPropertyValue( > obj, "TsExpiryTimestamp", EntityMode.POJO > ); > assertEquals( "Expiry timestamp from raw object", tsExpiryTimestamp, propertyValue ); > } > transaction.commit(); > } catch( HibernateException he ) > { > he.printStackTrace(); > fail( "Hibernate exception occurred." ); > if( transaction != null ) > { > transaction.rollback(); > } > } catch( Exception e ) > { > e.printStackTrace(); > fail( "Something else exception occured." ); > if( transaction != null ) > { > transaction.rollback(); > } > } > finally > { > if( currentSession != null ) > { > currentSession.close(); > } > } > } > Line 78 is > passwordClassMetaData.getPropertyValue( itspassword, "TsRecStat", EntityMode.POJO ); > The exception: > IllegalArgumentException in class: com.tokuii.baseapp.conf.redbull.v1.data.TsPassword, getter method of property: TsRecStat > org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.tokuii.baseapp.conf.redbull.v1.data.TsPassword.TsRecStat > at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171) > at org.hibernate.tuple.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:270) > at org.hibernate.tuple.AbstractEntityTuplizer.getPropertyValue(AbstractEntityTuplizer.java:280) > at org.hibernate.persister.entity.AbstractEntityPersister.getPropertyValue(AbstractEntityPersister.java:3252) > at com.tokuii.tests.component.hibernate.HibernateProxyTest.testAccessingTsPasswordProxyWithClassMetaDataAPI(Hibe > rnateProxyTest.java:78) > Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) > 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:145) > ... 50 more > Hbm.xml: > <?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"> > <hibernate-mapping> > <class name="com.tokuii.baseapp.conf.redbull.v1.data.TsPassword" table="TsPassword" proxy="com.tokuii.system.ITsPassword"> > <id name="Id" type="long" unsaved-value="0"> > <generator class="native"/> > </id> > <version column="TsVersion" name="TsVersion"/> > <many-to-one name="TsCreateUser" class="com.tokuii.baseapp.conf.redbull.v1.data.TsUser"/> > <many-to-one name="TsModifyUser" class="com.tokuii.baseapp.conf.redbull.v1.data.TsUser"/> > <property name="TsCreateTimestamp" type="timestamp" column="TsCreateTimestamp" not-null="false"/> > <property name="TsModifyTimestamp" type="timestamp" column="TsModifyTimestamp" not-null="false"/> > <property name="TsRecStat" type="java.lang.String" column="TsRecStat" not-null="false"/> > <property name="TsSysRowState" type="java.lang.String" column="TsSysRowState" not-null="false"/> > <property name="TsExpiryTimestamp" type="timestamp" column="TsExpiryTimestamp" not-null="false"/> > <property name="TsPassword" type="java.lang.String" column="TsPassword" not-null="false" length="50"/> > <property name="TsPwChangeRestriction" type="java.lang.Boolean" column="TsPwChangeRestriction" not-null="false"/> > <property name="TsPwValidity" type="java.lang.String" column="TsPwValidity" not-null="false"/> > </class> > </hibernate-mapping> > The TsPassword.java: > public class TsPassword implements com.tokuii.system.ITsPassword { > private java.lang.Long m_Id; > private int m_TsVersion = 1; > private com.tokuii.system.ITsUser m_TsCreateUser; > private com.tokuii.system.ITsUser m_TsModifyUser; > private java.util.Date m_TsCreateTimestamp; > private java.util.Date m_TsModifyTimestamp; > private java.lang.String m_TsRecStat = "A"; > private java.lang.String m_TsSysRowState = "P"; > private java.util.Date m_TsExpiryTimestamp; > private java.lang.String m_TsPassword; // Natural Identifier > private java.lang.Boolean m_TsPwChangeRestriction; > private java.lang.String m_TsPwValidity; > private com.tokuii.system.ITsUser m_TsUserId; // Natural Identifier > private java.util.Set m_TsPasswordIdTsUser; > /** Non-persistent field. */ > private java.util.Map m_NonDBFields; > public TsPassword() { > } > public java.lang.Long getId() { > return m_Id; > } > public void setId(java.lang.Long newId) { > m_Id = newId; > } > public int getTsVersion() { > return m_TsVersion; > } > public void setTsVersion(int newTsVersion) { > m_TsVersion = newTsVersion; > } > public Object getNonDBField(String fieldName) { > synchronized (this) { > if (m_NonDBFields == null) { > return null; > } > return m_NonDBFields.get(fieldName); > } > } > public void setNonDBField(String fieldName, Object value) { > synchronized (this) { > if (m_NonDBFields == null) { > m_NonDBFields = new java.util.HashMap(); > } > m_NonDBFields.put(fieldName, value); > } > } > public com.tokuii.system.ITsUser getTsCreateUser() { > return m_TsCreateUser; > } > public void setTsCreateUser(com.tokuii.system.ITsUser newTsCreateUser) { > m_TsCreateUser = newTsCreateUser; > } > public com.tokuii.system.ITsUser getTsModifyUser() { > return m_TsModifyUser; > } > public void setTsModifyUser(com.tokuii.system.ITsUser newTsModifyUser) { > m_TsModifyUser = newTsModifyUser; > } > public java.util.Date getTsCreateTimestamp() { > return m_TsCreateTimestamp; > } > public void setTsCreateTimestamp(java.util.Date newTsCreateTimestamp) { > m_TsCreateTimestamp = newTsCreateTimestamp; > } > public java.util.Date getTsModifyTimestamp() { > return m_TsModifyTimestamp; > } > public void setTsModifyTimestamp(java.util.Date newTsModifyTimestamp) { > m_TsModifyTimestamp = newTsModifyTimestamp; > } > public java.lang.String getTsRecStat() { > return m_TsRecStat; > } > public void setTsRecStat(java.lang.String newTsRecStat) { > m_TsRecStat = newTsRecStat; > } > public java.lang.String getTsSysRowState() { > return m_TsSysRowState; > } > public void setTsSysRowState(java.lang.String newTsSysRowState) { > m_TsSysRowState = newTsSysRowState; > } > public java.util.Date getTsExpiryTimestamp() { > return m_TsExpiryTimestamp; > } > public void setTsExpiryTimestamp(java.util.Date newTsExpiryTimestamp) { > m_TsExpiryTimestamp = newTsExpiryTimestamp; > } > public java.lang.String getTsPassword() { > return m_TsPassword; > } > public void setTsPassword(java.lang.String newTsPassword) { > m_TsPassword = newTsPassword; > } > public java.lang.Boolean getTsPwChangeRestriction() { > return m_TsPwChangeRestriction; > } > public void setTsPwChangeRestriction(java.lang.Boolean newTsPwChangeRestriction) { > m_TsPwChangeRestriction = newTsPwChangeRestriction; > } > public java.lang.String getTsPwValidity() { > return m_TsPwValidity; > } > public void setTsPwValidity(java.lang.String newTsPwValidity) { > m_TsPwValidity = newTsPwValidity; > } > public com.tokuii.system.ITsUser getTsUserId() { > return m_TsUserId; > } > public void setTsUserId(com.tokuii.system.ITsUser newTsUserId) { > m_TsUserId = newTsUserId; > } > public java.util.Set getTsPasswordIdTsUser() { > synchronized (this) { > if (m_TsPasswordIdTsUser == null) { > m_TsPasswordIdTsUser = new java.util.HashSet(); > } > } > return m_TsPasswordIdTsUser; > } > public void setTsPasswordIdTsUser(java.util.Set newTsPasswordIdTsUser) { > m_TsPasswordIdTsUser = newTsPasswordIdTsUser; > } > public boolean equals(Object o) { > if (this == o) { > return true; > } > if (o == null || getClass() != o.getClass()) { > return false; > } > final TsPassword that = (TsPassword) o; > if (m_TsPassword != null ? !m_TsPassword.equals(that.m_TsPassword) : that.m_TsPassword != null) { > return false; > } > Object thisId = m_TsUserId != null ? m_TsUserId.getId() : null; > Object thatId = that.m_TsUserId != null ? that.m_TsUserId.getId() : null; > if (thisId != null ? !thisId.equals(thatId) : thatId != null) { > return false; > } > return true; > } > public int hashCode() { > int result = 0; > result = 29 * result + (m_TsPassword != null ? m_TsPassword.hashCode() : 0); > result = 29 * result + (m_TsUserId != null && m_TsUserId.getId() != null ? m_TsUserId.getId().hashCode() : 0); > return result; > } > } > The interface: > public interface ITsPassword extends java.io.Serializable > { > java.lang.Long getId(); > void setId( java.lang.Long aLong ); > int getTsVersion(); > void setTsVersion( int index ); > java.lang.Object getNonDBField( java.lang.String elementLinkName ); > void setNonDBField( java.lang.String elementLinkName, java.lang.Object object ); > com.tokuii.system.ITsUser getTsCreateUser(); > void setTsCreateUser( com.tokuii.system.ITsUser iTsUser ); > java.util.Date getTsCreateTimestamp(); > void setTsCreateTimestamp( java.util.Date date ); > com.tokuii.system.ITsUser getTsModifyUser(); > void setTsModifyUser( com.tokuii.system.ITsUser iTsUser ); > java.util.Date getTsModifyTimestamp(); > void setTsModifyTimestamp( java.util.Date date ); > java.lang.String getTsRecStat(); > void setTsRecStat( java.lang.String elementLinkName ); > java.lang.String getTsSysRowState(); > void setTsSysRowState( java.lang.String elementLinkName ); > java.util.Date getTsExpiryTimestamp(); > void setTsExpiryTimestamp( java.util.Date date ); > java.lang.String getTsPassword(); > void setTsPassword( java.lang.String elementLinkName ); > java.lang.Boolean getTsPwChangeRestriction(); > void setTsPwChangeRestriction( java.lang.Boolean aBoolean ); > java.lang.String getTsPwValidity(); > void setTsPwValidity( java.lang.String elementLinkName ); > com.tokuii.system.ITsUser getTsUserId(); > void setTsUserId( com.tokuii.system.ITsUser iTsUser ); > java.util.Set getTsPasswordIdTsUser(); > void setTsPasswordIdTsUser( java.util.Set set ); > } -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira |