-->
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.  [ 2 posts ] 
Author Message
 Post subject: Join-fetch query stops working with query caching
PostPosted: Wed Mar 14, 2007 7:39 pm 
Newbie

Joined: Wed Mar 14, 2007 4:35 am
Posts: 3
Location: Melbourne, Australia
I am using join-fetch queries that are working fine with L2/query caching off.

However, enabling L2/query caching for these queries causes an IllegalArgumentException-object is not an instance of declaring class.

Using the debugger, I can see that the query has completed successfully, and the exception is thrown when saving the result into the cache.

The problem occurs reading the identifier via the BasicPropertyAccessor. The accessor is expecting a DarRecord instance, but it is receiving a DarRecord[] instance (with 1 valid entry) instead.

I have reviewed doco, google, bugs and forums with no success. As the query works without query caching, I cannot see how the mappings could be wrong (although I have tried many variations here). The exception seems to be within the Hibernate core - so it does not appear to be related to cache provider / database / JDBC etc.

Has anyone got any ideas?

In constructing the post - I have realised that Hibernate is also performing a subselect query after the join - not sure if this is relevant?

Hibernate version:
3.2.1 (with built in EhCacheProvider)
Mapping documents:

hibernate.cfg.xml
Code:
<hibernate-configuration>
   <session-factory>
      <property name="hibernate.connection.driver_class">@db_driver@</property>
      <property name="hibernate.connection.url">@db_url@</property>
      <property name="hibernate.connection.username">@db_user@</property>
      <property name="hibernate.connection.password">@db_pass@</property>
      <property name="hibernate.dialect">
         org.hibernate.dialect.SQLServerDialect
      </property>
      
      <property name="hibernate.show_sql">true</property>
      <property name="hibernate.format_sql">false</property>
      <property name="hibernate.generate_statistics">true</property>
      
        <property name="c3p0.max_size">10</property>
        <property name="c3p0.min_size">2</property>
        <property name="c3p0.timeout">5000</property>
        <property name="c3p0.max_statements">100</property>
        <property name="c3p0.idle_test_period">3000</property>
        <property name="c3p0.acquire_increment">2</property>
        <property name="c3p0.validate">false</property>
       
          <!-- Second-level caching -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
        <property name="hibernate.cache.use_query_cache">true</property>
       
        <property name="hibernate.transaction.flush_before_completion">
           true
        </property>

        <property name="hibernate.transaction.auto_close_session">
           true
        </property>

       (OTHER MAPPINGS REMOVED HERE)
 
        <mapping resource="com/xxx/DarEntity.hbm.xml"/>
        <mapping resource="com/xxx/DarRecord.hbm.xml"/>
        <mapping resource="com/xxx/DarField.hbm.xml"/>
        <mapping resource="com/xxx/DarReference.hbm.xml"/>      
      
   </session-factory>
</hibernate-configuration>


DarRecord.hbm.xml
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="com.xxx">
  <class name="DarRecord" table="DAR_RECORD">
     <cache usage="read-write"/>
    <id name="recordID" column="RECORD_ID" type="long">
      <generator class="identity"/>
    </id>
    <property name="recordName" column="RECORD_NAME"/>
    <property name="recordUserKey" column="RECORD_USER_KEY"/>
    <bag name="fields" inverse="true" lazy="false" cascade="all,delete-orphan" fetch="join">
      <key column="RECORD_ID"/>
      <one-to-many class="DarField"/>
    </bag>
    <set name="referencedBy" lazy="true" fetch="subselect" where="TO_DISCRIMINATOR = 'REC'">
      <key column="TO_KEY"/>
      <one-to-many class="DarFieldReference"/>
    </set>
    <many-to-one name="entity" class="DarEntity" column="ENTITY_ID"/>
  </class>
</hibernate-mapping>


DarField.hbm.xml
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="com.xxx">
  <class name="DarField" table="DAR_FIELD">
    <id name="fieldID" column="FIELD_ID" type="long">
      <generator class="identity"/>
    </id>
    <property name="fieldName" column="FIELD_NAME"/>
    <property name="fieldValue" column="FIELD_VALUE"/>
   
    <!-- Our parent record -->
    <many-to-one name="record" class="DarRecord" column="RECORD_ID"/>
   
    <!-- Optional reference field -->
    <bag name="references" lazy="false" inverse="true" cascade="all,delete-orphan" fetch="subselect">
      <key column="FROM_KEY"/>
      <one-to-many class="DarFieldReference"/>
    </bag>
   
  </class>
</hibernate-mapping>


DarEntity.hbm.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.xxx">
  <class name="DarEntity" table="DAR_ENTITY">
    <id name="entityID" column="ENTITY_ID">
            <generator class="identity" />
    </id>
    <property name="dataPath" column="DATAPATH"/>
    <property name="repEntityType" column="REP_ENTITY_TYPE"/>
  </class>
</hibernate-mapping>


DarReference.hbm.xml
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="com.xxx">
  <class name="DarReference" table="DAR_REFERENCE" >
    <id name="referenceID" column="REFERENCE_ID" type="long">
      <generator class="identity"/>
    </id>
   
    <!--  These values (fromDiscriminator/fromKey) are set by subclasses below. -->
    <discriminator column="FROM_DISCRIMINATOR" type="string" not-null="true"/>
    <property name="fromKey" column="FROM_KEY" type="long" not-null="true" update="false" insert="false"/>
   
    <!--  The target of the reference -->
    <property name="toDiscriminator" column="TO_DISCRIMINATOR" type="string" not-null="true"/>
    <property name="toKey" column="TO_KEY" type="long" not-null="true"/>
   
    <!--  Subclasses of the reference (depending on the source of the reference) -->
    <subclass name="DarFieldReference" discriminator-value="FLD" extends="DarReference">
       <many-to-one name="field" class="DarField" column="FROM_KEY" not-null="true"/>
    </subclass>
  </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Code:
      Session session = HibernateUtil.getSession();
      Query query = session.createQuery("from DarRecord DR left join fetch DR.fields DF where DR.entity.dataPath=:dataPath");
      query.setString("dataPath", dataPath);
      query.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
      // Uncomment next line to raise exception
      query.setCacheable(true);
      return query.list();


Full stack trace of any exception that occurs:
Code:
org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.xxx.DarRecord.recordID
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:171)
   at org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:183)
   at org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3539)
   at org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3255)
   at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:181)
   at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:218)
   at org.hibernate.type.ManyToOneType.disassemble(ManyToOneType.java:163)
   at org.hibernate.cache.StandardQueryCache.put(StandardQueryCache.java:80)
   at org.hibernate.loader.Loader.putResultInQueryCache(Loader.java:2185)
   at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2129)
   at org.hibernate.loader.Loader.list(Loader.java:2087)
   at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:388)
   at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
   at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
   at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
   at com.xxx.DarRecordDao.getDarList(DarRecordDao.java:30)
   at com.xxx.TestDarRecord.testListCouncils(TestDarRecord.java:33)
   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:324)
   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 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
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:324)
   at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
   ... 30 more

Name and version of the database you are using:
SQL Server 2000
The generated SQL (show_sql=true):
Code:
Hibernate: select darrecord0_.RECORD_ID as RECORD1_21_0_, fields1_.FIELD_ID as FIELD1_22_1_, darrecord0_.RECORD_NAME as RECORD2_21_0_, darrecord0_.RECORD_USER_KEY as RECORD3_21_0_, darrecord0_.ENTITY_ID as ENTITY4_21_0_, fields1_.FIELD_NAME as FIELD2_22_1_, fields1_.FIELD_VALUE as FIELD3_22_1_, fields1_.RECORD_ID as RECORD4_22_1_, fields1_.RECORD_ID as RECORD4_0__, fields1_.FIELD_ID as FIELD1_0__ from DAR_RECORD darrecord0_ left outer join DAR_FIELD fields1_ on darrecord0_.RECORD_ID=fields1_.RECORD_ID, DAR_ENTITY darentity2_ where darrecord0_.ENTITY_ID=darentity2_.ENTITY_ID and darentity2_.DATAPATH=?
Hibernate: select references0_.FROM_KEY as FROM3_1_, references0_.REFERENCE_ID as REFERENCE1_1_, references0_.REFERENCE_ID as REFERENCE1_23_0_, references0_.FROM_KEY as FROM3_23_0_, references0_.TO_DISCRIMINATOR as TO4_23_0_, references0_.TO_KEY as TO5_23_0_ from DAR_REFERENCE references0_ where references0_.FROM_KEY in (select fields1_.FIELD_ID from DAR_RECORD darrecord0_ left outer join DAR_FIELD fields1_ on darrecord0_.RECORD_ID=fields1_.RECORD_ID, DAR_ENTITY darentity2_ where darrecord0_.ENTITY_ID=darentity2_.ENTITY_ID and darentity2_.DATAPATH=?)

Debug level Hibernate log excerpt:
Code:
- Hibernate 3.2.1
- hibernate.properties not found
- Bytecode provider name : cglib
- using JDK 1.4 java.sql.Timestamp handling
- configuring from resource: hibernate.standalone.cfg.xml
- Configuration resource: hibernate.standalone.cfg.xml
(OTHER MAPPINGS REMOVED HERE)
- Reading mappings from resource : com/xxx/DarEntity.hbm.xml
- Mapping class: com.xxx.DarEntity -> DAR_ENTITY
- Reading mappings from resource : com/xxx/DarRecord.hbm.xml
- Mapping class: com.xxx.DarRecord -> DAR_RECORD
- Reading mappings from resource : com/xxx/DarField.hbm.xml
- Mapping class: com.xxx.DarField -> DAR_FIELD
- Reading mappings from resource : com/xxx/DarReference.hbm.xml
- Mapping class: com.xxx.DarReference -> DAR_REFERENCE
- Mapping subclass: com.xxx.DarFieldReference -> DAR_REFERENCE
- Configured SessionFactory: null
- Mapping collection: com.xxx.DarRecord.fields -> DAR_FIELD
- Mapping collection: com.xxx.DarRecord.referencedBy -> DAR_REFERENCE
- Mapping collection: com.xxx.DarField.references -> DAR_REFERENCE
- C3P0 using driver: net.sourceforge.jtds.jdbc.Driver at URL: jdbc:jtds:sqlserver://XXX
- Connection properties: {user=XXX, password=****}
- autocommit mode: false
- MLog clients using log4j logging.
- Initializing c3p0-0.9.0 [built 11-July-2005 00:43:29 -0400; debug? true; trace: 10]
- Initializing c3p0 pool... com.mchange.v2.c3p0.PoolBackedDataSource@873723 [ connectionPoolDataSource -> com.mchange.v2.c3p0.WrapperConnectionPoolDataSource@1302fc5 [ acquireIncrement -> 2, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1302fc5, idleConnectionTestPeriod -> 3000, initialPoolSize -> 2, maxIdleTime -> 5000, maxPoolSize -> 10, maxStatements -> 100, maxStatementsPerConnection -> 0, minPoolSize -> 2, nestedDataSource -> com.mchange.v2.c3p0.DriverManagerDataSource@e93999 [ description -> null, driverClass -> null, factoryClassLocation -> null, identityToken -> e93999, jdbcUrl -> jdbc:jtds:sqlserver://XXX, properties -> {user=******, password=******} ], preferredTestQuery -> null, propertyCycle -> 300, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, usesTraditionalReflectiveProxies -> false ], factoryClassLocation -> null, identityToken -> 873723, numHelperThreads -> 3 ]
- RDBMS: Microsoft SQL Server, version: 08.00.0760
- JDBC driver: jTDS Type 4 JDBC Driver for MS SQL Server and Sybase, version: 1.0.3
- Using dialect: org.hibernate.dialect.SQLServerDialect
- Using default transaction strategy (direct JDBC transactions)
- No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
- Automatic flush during beforeCompletion(): enabled
- Automatic session close at end of transaction: enabled
- Scrollable result sets: enabled
- JDBC3 getGeneratedKeys(): enabled
- Connection release mode: auto
- Default batch fetch size: 1
- Generate SQL with comments: disabled
- Order SQL updates by primary key: disabled
- Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
- Using ASTQueryTranslatorFactory
- Query language substitutions: {}
- JPA-QL strict compliance: disabled
- Second-level cache: enabled
- Query cache: enabled
- Cache provider: org.hibernate.cache.EhCacheProvider
- Optimize cache for minimal puts: disabled
- Structured second-level cache entries: disabled
- Query cache factory: org.hibernate.cache.StandardQueryCacheFactory
- Echoing all SQL to stdout
- Statistics: enabled
- Deleted entity synthetic identifier rollback: disabled
- Default entity-mode: pojo
- building session factory
- No configuration found. Configuring ehcache from ehcache-failsafe.xml  found in the classpath: jar:file:/C:/Dev/Workspaces/SB/common/lib/hibernate/ehcache-1.2.3.jar!/ehcache-failsafe.xml
- Could not find configuration [com.xxx.DarRecord]; using defaults.
- Not binding factory to JNDI, no JNDI name configured
- starting update timestamps cache at region: org.hibernate.cache.UpdateTimestampsCache
- Could not find configuration [org.hibernate.cache.UpdateTimestampsCache]; using defaults.
- starting query cache at region: org.hibernate.cache.StandardQueryCache
- Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults.
Hibernate: select darrecord0_.RECORD_ID as RECORD1_21_0_, fields1_.FIELD_ID as FIELD1_22_1_, darrecord0_.RECORD_NAME as RECORD2_21_0_, darrecord0_.RECORD_USER_KEY as RECORD3_21_0_, darrecord0_.ENTITY_ID as ENTITY4_21_0_, fields1_.FIELD_NAME as FIELD2_22_1_, fields1_.FIELD_VALUE as FIELD3_22_1_, fields1_.RECORD_ID as RECORD4_22_1_, fields1_.RECORD_ID as RECORD4_0__, fields1_.FIELD_ID as FIELD1_0__ from DAR_RECORD darrecord0_ left outer join DAR_FIELD fields1_ on darrecord0_.RECORD_ID=fields1_.RECORD_ID, DAR_ENTITY darentity2_ where darrecord0_.ENTITY_ID=darentity2_.ENTITY_ID and darentity2_.DATAPATH=?
Hibernate: select references0_.FROM_KEY as FROM3_1_, references0_.REFERENCE_ID as REFERENCE1_1_, references0_.REFERENCE_ID as REFERENCE1_23_0_, references0_.FROM_KEY as FROM3_23_0_, references0_.TO_DISCRIMINATOR as TO4_23_0_, references0_.TO_KEY as TO5_23_0_ from DAR_REFERENCE references0_ where references0_.FROM_KEY in (select fields1_.FIELD_ID from DAR_RECORD darrecord0_ left outer join DAR_FIELD fields1_ on darrecord0_.RECORD_ID=fields1_.RECORD_ID, DAR_ENTITY darentity2_ where darrecord0_.ENTITY_ID=darentity2_.ENTITY_ID and darentity2_.DATAPATH=?)
- IllegalArgumentException in class: com.xxx.DarRecord, getter method of property: recordID


Top
 Profile  
 
 Post subject: Does query caching work with fetch join queries?
PostPosted: Sun Mar 18, 2007 7:07 pm 
Newbie

Joined: Wed Mar 14, 2007 4:35 am
Posts: 3
Location: Melbourne, Australia
Has anyone else tried query caching with fetch-join queries and if so, did you managed to get it working?

I have spent a lot of time trying to understand why this does not work for me, and I guess I want to know if it possible or if I am wasting my time on an unsupported combination.

Thanks in advance for any feedback!


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