-->
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.  [ 5 posts ] 
Author Message
 Post subject: ClassCastException from CGLIB when using Cache and comp Key
PostPosted: Wed Jul 06, 2005 10:55 am 
Newbie

Joined: Tue Mar 08, 2005 7:16 am
Posts: 8
Hi all,

Specific details are below but here's a description. We're using Hibernate along with the 2nd level caching for our read only app. Everything works fine the first time the app is started and the caches are populated (and persisted to disk).

However, if we bounce the app we get a nasty stack trace. This is for a new entity that we've included that uses a composite key, HistoricCreditRatingKey, for the entity HistoricCreditRating. Its the first time that we've used a composite key and so the first time we've hit this problem.

The issue appears to be that when we ask Hibernate to load the object it finds it in the cache (no SQL is generated so its not hitting the database) but fails to instantiate it with the ClassCastException, but the stack trace doesn't make much sense. We're now stuck and its killing our app!

PLEASE HELP.

Rob

Hibernate version:
Hibernate 3.05

Mapping documents:
Code:
<class
    name="com.db.csa.domain.HistoricCreditRating"
    table="DM_FI_ISSUER_RATING"
    where="s_valid_from &lt; sysdate and s_valid_to is null"
>

    <composite-id name="key" class="com.db.csa.domain.HistoricCreditRatingKey">
   
       <key-property
          name="companyId"
          column="ID_BB_COMPANY"
             type="java.lang.String"
           length="8"
       />
       
       <key-property
           name="ratingType"
           column="RATING_TYP"
           type="java.lang.String"
           length="30"
       />
   
       <key-property
           name="ratingCompany"
           column="RATING_AGENCY"
          type="java.lang.String"
          length="16"
      />
   </composite-id>
   
   <property
       name="companyId"
      column="ID_BB_COMPANY"
         type="java.lang.String"
       length="8"
       insert="false"
       update="false"
   />

    <property
        name="rating"
        column="rating"
        type="java.lang.String"
        length="8"
    />
.
.
.


Here's the highlight of the HistoricCreditRating class. Each property has associated getter and setter values:
Code:
    private HistoricCreditRatingKey key;
    private String rating;
    private String ratingChangeDirection;
    private YearMonthDay startDate;
    private YearMonthDay endDate;
    private String companyId;


The key. The member variables have associated getters/setters and we've implemented the appropriate methods for the UserType interface:

Code:
public class HistoricCreditRatingKey implements UserType, Serializable{
    private String companyId;
    private String ratingType;
    private String ratingCompany;


Code between sessionFactory.openSession() and session.close():
Hmm, tricky one. We're using some batching stuff along with lazy objects. The method that kicks things off:
Code:
        DataAccessSession session = new DataAccessSession();
        for (Issuer issuer : session.getIssuerStore().getAllIssuers()) {
                 getBondsForIssuer(issuer, session);   
        }
        session.close();

The method that is called is this:

Code:
    public List<HistoricCreditRating> getCreditRatingsForIssuer(Issuer issuer) throws CsaDAOException {
            String companyId = issuer.getIdBbCompany();
            if (companyId != null) {
                return ratingCollectionFactory.createObject(companyId);
            }
            return Collections.emptyList();
    }

The code that does the batching and then calls the values:
Code:
                Map<String, String> issuerTickers = new HashMap<String, String>(idList.size());
               
                for (String identifier : idList){
                    issuerTickers.put(identifier, identifier);
                   
                }
               
                Criteria query = session.createCriteria(HistoricCreditRating.class);
                //query.setCacheable(true);
               
                query.add(Restrictions.in("companyId", issuerTickers.keySet()));
                query.addOrder(Order.asc("companyId"));
                List<HistoricCreditRating> ratings = query.list();
               
                Map<String, ArrayList<HistoricCreditRating>> companyRatingCollections = new HashMap<String, ArrayList<HistoricCreditRating>>(idList.size());
                String currentIdentifier = null;
                ArrayList<HistoricCreditRating> companyRatingCollection = null;
                // Due to the ordering of the query we can assume that if a ticker changes from one bond to the
                // next then we are looking at bonds for a new issuer
                for (HistoricCreditRating historicCreditRating : ratings){
                        if (currentIdentifier == null || !historicCreditRating.getCompanyId().equals(currentIdentifier)){
                            //LOG.debug(companyBondCollection.toString());
                            currentIdentifier = issuerTickers.get(historicCreditRating.getCompanyId());
                            companyRatingCollection = new ArrayList<HistoricCreditRating>();
                            companyRatingCollections.put(currentIdentifier, companyRatingCollection);
                        }
                        companyRatingCollection.add(historicCreditRating);
                }
                LOG.debug(companyRatingCollections.toString());
                return companyRatingCollections;


Full stack trace of any exception that occurs:
Code:
2005-07-06 15:33:22,245 INFO  org.hibernate.impl.SessionFactoryImpl  - Checking 0 named queries
Exception in thread "main" com.db.csa.dao.core.CsaDAOException: Error searching for class java.util.ArrayList by hibernate id [825197]: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of com.db.csa.domain.HistoricCreditRatingKey.?
   at com.db.csa.dao.database.CachingBatchingLazyCollectionFactory.getObjectFromHibernate(CachingBatchingLazyCollectionFactory.java:66)
   at com.db.csa.dao.database.CachingBatchingLazyCollectionFactory.getObjectsFromHibernate(CachingBatchingLazyCollectionFactory.java:50)
   at com.db.csa.dao.database.CachingBatchingLazyCollectionFactory.createObject(CachingBatchingLazyCollectionFactory.java:41)
   at com.db.csa.dao.database.HistoricCreditRatingStoreSession.getCreditRatingsForIssuer(HistoricCreditRatingStoreSession.java:62)
   at com.db.csa.dao.database.CSAPostLoadEventListener.injectIssuerCreditRatings(CSAPostLoadEventListener.java:120)
   at com.db.csa.dao.database.CSAPostLoadEventListener.injectDependenciesIntoIssuer(CSAPostLoadEventListener.java:75)
   at com.db.csa.dao.database.CSAPostLoadEventListener.onPostLoad(CSAPostLoadEventListener.java:49)
   at org.hibernate.event.def.DefaultLoadEventListener.assembleCacheEntry(DefaultLoadEventListener.java:528)
   at org.hibernate.event.def.DefaultLoadEventListener.loadFromSecondLevelCache(DefaultLoadEventListener.java:460)
   at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:314)
   at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:113)
   at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:167)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:79)
   at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:655)
   at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:261)
   at org.hibernate.type.ManyToOneType.assemble(ManyToOneType.java:160)
   at org.hibernate.cache.StandardQueryCache.get(StandardQueryCache.java:91)
   at org.hibernate.loader.Loader.list(Loader.java:1549)
   at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:111)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1322)
   at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:300)
   at com.db.csa.dao.database.IssuerStoreSession.getAllIssuers(IssuerStoreSession.java:59)
   at com.db.csa.devtools.DumpCSABondsInDBIQ.main(DumpCSABondsInDBIQ.java:36)
Caused by: org.hibernate.PropertyAccessException: exception getting property value with CGLIB (set hibernate.cglib.use_reflection_optimizer=false for more info) getter of com.db.csa.domain.HistoricCreditRatingKey.?
   at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:42)
   at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:257)
   at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:158)
   at org.hibernate.engine.EntityKey.getHashCode(EntityKey.java:68)
   at org.hibernate.engine.EntityKey.<init>(EntityKey.java:41)
   at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:69)
   at org.hibernate.impl.SessionImpl.get(SessionImpl.java:621)
   at org.hibernate.impl.SessionImpl.get(SessionImpl.java:614)
   at com.db.csa.dao.database.CachingBatchingLazyCollectionFactory.getObjectFromHibernate(CachingBatchingLazyCollectionFactory.java:64)
   ... 22 more
Caused by: java.lang.ClassCastException: java.lang.String
   at com.db.csa.domain.HistoricCreditRatingKey$$BulkBeanByCGLIB$$6aee0c2a.getPropertyValues(<generated>)
   at net.sf.cglib.beans.BulkBean.getPropertyValues(BulkBean.java:48)
   at org.hibernate.tuple.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:39)
   ... 30 more


Name and version of the database you are using:
Oracle 9i
The generated SQL (show_sql=true):
None generated


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 06, 2005 3:15 pm 
CGLIB Developer
CGLIB Developer

Joined: Thu Aug 28, 2003 1:44 pm
Posts: 1217
Location: Vilnius, Lithuania
"set hibernate.cglib.use_reflection_optimizer=false for more info"


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 07, 2005 5:12 am 
Newbie

Joined: Tue Mar 08, 2005 7:16 am
Posts: 8
I have. From the hibernate.cfg.xml:

Code:
<property name="hibernate.cglib.use_reflection_optimizer">
    false
</property>


That gave me the rest of the stack trace but nothing else useful.

I'e even tried debugging the app but the code that fails is in the generated proxy class from CGLIB.

Thanks,

Rob


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 07, 2005 9:13 am 
Newbie

Joined: Tue Mar 08, 2005 7:16 am
Posts: 8
Got fed up with the cack that was happening. I've worked around the issue by ditching the combined ID and replacing it with this, in the mapping file:

Code:
    <id name="key" column="ID_BB_COMPANY||RATING_TYP||RATING_AGENCY">
       <generator class="assigned" />
    </id>   

   <property
       name="companyId"
      column="ID_BB_COMPANY"
         type="java.lang.String"
       length="8"
   />
   
    <property
        name="ratingType"
        column="RATING_TYP"
        type="java.lang.String"
        length="30"
    />
    <property
        name="ratingCompany"
        column="RATING_AGENCY"
       type="java.lang.String"
       length="16"
   />



Now the key is a faked key. Its a complete bodge but it works, and given whats happening in London today, right outside my office, I can't be bothered to spend time investigating it any further,


Top
 Profile  
 
 Post subject:
PostPosted: Sat Feb 25, 2006 8:10 am 
Newbie

Joined: Sat Feb 25, 2006 8:08 am
Posts: 2
Hi, finally is there a better solution to avoid this exception, than using a fake id ?

i tried to override the equals and hashcode method in the class but the exception is still here

thanks


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