-->
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.  [ 4 posts ] 
Author Message
 Post subject: ClassCastException when mapping a Custom Collection Type
PostPosted: Mon Mar 20, 2006 3:32 pm 
Newbie

Joined: Tue Jul 05, 2005 3:21 pm
Posts: 6
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp
I'm implementing an UserCollectionType for a custom collection that
extends HashMap.

With the log4j level set to 'debug' I get ClassCastException at org.hibernate.type.CollectionType.toLoggableString(CollectionType.java:152), when retrieving the graph.
If log4j level is set to 'WARN' or 'INFO" it works fine.
Any help?
The classes are:

public interface InfoMap extends Map {
public BigDecimal getTotal();
public Collection getAccounts();
public AccountNumber[] getAccountList();
}

public class InfoMapImpl extends HashMap implements InfoMap {
public InfoMapImpl() {
super();
}
public BigDecimal getTotal() {

BigDecimal disbTotal = new BigDecimal(0);

for (Iterator a = this.values().iterator(); a.hasNext();) {
Info disbInfo = (Info)a.next();

BigDecimal disbAmount = disbInfo.getDisAmount().getAmount();

if (disbAmount == null) {
throw new RuntimeException("Missing amount");
}
else {
disbTotal = disbTotal.add(disbAmount);
}
}
return disbTotal;
}
public Collection getAccounts() {
ArrayList list = new ArrayList();
for (Iterator a = this.values().iterator(); a.hasNext();) {
Info disbInfo = (Info)a.next();
if (disbInfo.getAccountNumber() == null) {
throw new RuntimeException("Missing account");
}
else {
list.add(disbInfo);
}
}
return list;
}
public AccountNumber[] getAccountList() {
return (AccountNumber[])getAccounts().toArray(new AccountNumber[0]);
}
}

THE WRAPPER
public class PersistentInfoMapImpl extends PersistentMap implements InfoMap {
public PersistentInfoMapImpl(SessionImplementor session) {
super(session);
}

public PersistentInfoMapImpl(SessionImplementor session, InfoMap map) {
super(session, map);
}
public BigDecimal getTotal() {

BigDecimal disbTotal = new BigDecimal(0);

for (Iterator a = this.values().iterator(); a.hasNext();) {
Info disbInfo = (Info)a.next();

BigDecimal disbAmount = disbInfo.getDisAmount().getAmount();

if (disbAmount == null) {
throw new RuntimeException("Missing amount");
}
else {
disbTotal = disbTotal.add(disbAmount);
}
}
return disbTotal;
}
public Collection getAccounts() {
ArrayList list = new ArrayList();
for (Iterator a = this.values().iterator(); a.hasNext();) {
Info disbInfo = (Info)a.next();
if (disbInfo.getAccountNumber() == null) {
throw new RuntimeException("Missing account");
}
else {
list.add(disbInfo);
}
}
return list;
}
public AccountNumber[] getAccountList() {
return (AccountNumber[])getAccounts().toArray(new AccountNumber[0]);
}
}

THE USER COLLECTION TYPE
public class InfoMapImplType implements UserCollectionType {
public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) throws HibernateException {
return new PersistentInfoMapImpl(session);
}
public PersistentCollection wrap(SessionImplementor session, Object collection) {
if (session.getEntityMode() == EntityMode.DOM4J) {
throw new IllegalStateException("dom4j not supported");
}
else {
return new PersistentInfoMapImpl(session, (InfoMap)collection);
}
}

public Iterator getElementsIterator(Object collection) {
return ((InfoMap)collection).values().iterator();
}

public boolean contains(Object collection, Object entity) {
return ((InfoMap)collection).values().contains(entity);
}
public Object indexOf(Object collection, Object entity) {
return null;
}
public Object replaceElements(Object original, Object target, CollectionPersister persister, Object owner, Map copyCache, SessionImplementor session)
throws HibernateException {
InfoMap result = (InfoMap)target;
result.clear();
result.putAll((InfoMap)original);
return result;
}
public Object instantiate() {
return new InfoMapImpl();
}
}

Hibernate version:
3.1.2
Mapping documents:
<map
name="Infos"
collection-type="com.persistence.hibernate.usertype.InfoMapImplType"
cascade="all-delete-orphan"
lazy="false"
outer-join="true"
table="INFO"
fetch="join"
inverse="true">
<key not-null="true">
<column
name="REF_NUM"
not-null="true">
</column>
</key>
<map-key type="integer">
<column
name="SEQ_NUM"
not-null="true">
</column>
</map-key>
<one-to-many
class="com.sys.details.InfoImpl" />
</map

Hibernate version:
3.1.2
Mapping documents:
<map
name="Infos"
collection-type="com.persistence.hibernate.usertype.InfoMapImplType"
cascade="all-delete-orphan"
lazy="false"
outer-join="true"
table="INFO"
fetch="join"
inverse="true">
<key not-null="true">
<column
name="REF_NUM"
not-null="true">
</column>
</key>
<map-key type="integer">
<column
name="SEQ_NUM"
not-null="true">
</column>
</map-key>
<one-to-many
class="com.sys.details.InfoImpl" />
</map>
Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:
java.lang.ClassCastException: com.persistence.hibernate.usertype.PersistentInfoMapImpl
at org.hibernate.type.CollectionType.toLoggableString(CollectionType.java:152)
at org.hibernate.pretty.Printer.toString(Printer.java:53)
at org.hibernate.pretty.Printer.toString(Printer.java:90)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:97)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1009)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:356)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:490)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:495)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:468)
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(TransactionAspectSupport.java:258)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
at $Proxy1.retrieveCreditApplication(Unknown Source)
at test.com.hibernate.MappingTestCase.testSaveApplication(MappingTestCase.java:367)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41)
at java.lang.reflect.Method.invoke(Method.java:386)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:392)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:276)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:167)
Name and version of the database you are using:
DB2 OS/390 8.1.0
The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:


Top
 Profile  
 
 Post subject: ClassCastException in CollectionType
PostPosted: Tue Mar 21, 2006 9:34 am 
Newbie

Joined: Fri Aug 19, 2005 4:39 am
Posts: 5
We had the same problem when using a CustomCollectionType.

The method toLoggableString in CollectionType tries to cast a UserCollectionType to ord.dom4j.Element, so we downloaded hibernate source and changed it as follows:

public String toLoggableString(Object value, SessionFactoryImplementor factory)
throws HibernateException {

if ( value == null ) return "null";

if ( Hibernate.isInitialized( value ) ) {
if ( getReturnedClass().isInstance(value) ) {
List list = new ArrayList();
Type elemType = getElementType( factory );
Iterator iter = getElementsIterator( value );
while ( iter.hasNext() ) {
list.add( elemType.toLoggableString( iter.next(), factory ) );
}
return list.toString();
} else {
if (value instanceof Element) {
// for DOM4J "collections" only
return ( (Element) value ).asXML(); //TODO: it would be better if this was done at the higher level by Printer
} else {
return value.toString();
}

}
}
else {
return "<uninitialized>";
}

}

In original code getReturnedClass().isInstance(value) fails in case of CustomCollectionTypes, so it tries in the else to cast the value (which is your CustomCollectionType) to org.dom4j.Element.

getReturnedClass() is unfortunatly not part of the UserCollectionType interface, so this was the only solution we found.

Hope this helps!


Top
 Profile  
 
 Post subject: ClassCastException when mapping a Custom Collection Type
PostPosted: Tue Mar 21, 2006 11:33 am 
Newbie

Joined: Tue Jul 05, 2005 3:21 pm
Posts: 6
Yes it helps. It confirms what we found too.

Has this been reported as a bug ?
I couldn't find one.
Here changing the Hibernate API is not an option.
We'll stay with the log set to 'info' for now.

Thanks again


Top
 Profile  
 
 Post subject: BugReport
PostPosted: Wed Mar 22, 2006 6:09 am 
Newbie

Joined: Fri Aug 19, 2005 4:39 am
Posts: 5
I've reported it to JIRA, let's see what the hibernate guys will do!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.