-->
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.  [ 3 posts ] 
Author Message
 Post subject: PropertyAccessException when using Query Cache
PostPosted: Wed Jul 01, 2009 9:54 am 
Newbie

Joined: Mon Oct 20, 2008 6:26 pm
Posts: 3
Hi,

I'm currently trying to migrate from Hibernate 3.2.6 to Hibernate 3.3.2 GA. However, whenever I try to query for objects with the query cache enabled I get an exception like the one shown below. When I disable the query cache it works fine. I get this with various criteria queries.

As the stack trace shows, the exception happens calculating the hash code for the QueryKey. I'm sure the criteria query itself is valid, as it works correctly with the query cache turned off, and works fine with 3.2.6.

This definitely isn't the usual setting a value to the wrong datatype, or assigning null to a primitive problem.


Code:
Caused by: com.ubs.eq.del.stomp.core.persistence.StompPersistenceException: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.ubs.eq.del.rmp.model.order.ExternalSystemOrderIdentifier.clientOrderId
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistence.executeInTransaction(HibernatePersistence.java:114)
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistenceClosureFactory$1Closure.execute(HibernatePersistenceClosureFactory.java:13)
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistenceClosureFactory$1Closure.execute(HibernatePersistenceClosureFactory.java:1)
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistence.withSession(HibernatePersistence.java:79)
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistence.inTransaction(HibernatePersistence.java:87)
   at com.ubs.eq.del.stomp.core.persistence.StompNestedTransactions$1.execute(StompNestedTransactions.java:33)
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistence$1.execute(HibernatePersistence.java:100)
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistence.execute(HibernatePersistence.java:119)
   at com.ubs.eq.del.stomp.core.persistence.hibernate.HibernatePersistence.executeInTransaction(HibernatePersistence.java:111)
   ... 28 more
Caused by: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of com.ubs.eq.del.rmp.model.order.ExternalSystemOrderIdentifier.clientOrderId
   at org.hibernate.property.DirectPropertyAccessor$DirectGetter.get(DirectPropertyAccessor.java:58)
   at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:87)
   at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:93)
   at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:109)
   at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:376)
   at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:194)
   at org.hibernate.cache.QueryKey.generateHashCode(QueryKey.java:194)
   at org.hibernate.cache.QueryKey.<init>(QueryKey.java:173)
   at org.hibernate.cache.QueryKey.generateQueryKey(QueryKey.java:128)
   at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2144)
   at org.hibernate.loader.Loader.list(Loader.java:2121)
   at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:118)
   at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1597)
   at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:306)
   at org.hibernate.impl.CriteriaImpl.uniqueResult(CriteriaImpl.java:328)
   at com.ubs.eq.del.rmp.persistence.hibernate.HibernateOrderBook.find(HibernateOrderBook.java:41)


Anyone know what's causing this, and how to fix it?

Thanks,

Jim


Top
 Profile  
 
 Post subject: Re: PropertyAccessException when using Query Cache
PostPosted: Thu Jul 02, 2009 8:52 am 
Newbie

Joined: Mon Oct 20, 2008 6:26 pm
Posts: 3
OK, I've managed to narrow this down to only affecting ComponentTypes.

Here's an example:

Code:
package com.jc.test;

import javax.persistence.Embeddable;

@Embeddable
public class ExternalSystemOrderIdentifier {

   private String sourceSystem;
   private Long externalId;
   
   public ExternalSystemOrderIdentifier() {
      // hibernate
   }
   
   public ExternalSystemOrderIdentifier(String sourceSystem, Long externalId) {
      this.sourceSystem = sourceSystem;
      this.externalId = externalId;
   }

   public String getSourceSystem() {
      return sourceSystem;
   }

   public Long getExternalId() {
      return externalId;
   }
}


Code:
package com.jc.test;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "orders")
public class Order {

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;
   
   @Embedded
   private ExternalSystemOrderIdentifier externalIdentifier;
   private String symbol;
   private int quantity;
   private double price;
   
   public Order() {
      // hibernate
   }
   
   public Order(ExternalSystemOrderIdentifier externalIdentifier, String symbol, int quantity, double price) {
      this.externalIdentifier = externalIdentifier;
      this.symbol = symbol;
      this.quantity = quantity;
      this.price = price;
   }

   public ExternalSystemOrderIdentifier getExternalIdentifier() {
      return externalIdentifier;
   }

   public String getSymbol() {
      return symbol;
   }

   public int getQuantity() {
      return quantity;
   }

   public double getPrice() {
      return price;
   }
   
   public Long getId(){
      return id;
   }
}


Code:
package com.jc.test;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.criterion.Restrictions;


public class OrderBook {

   private final SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
   
   @SuppressWarnings("unchecked")
   public List<Order> find(ExternalSystemOrderIdentifier identifier) {
      Session session = sessionFactory.openSession();
      try {
         return session.createCriteria(Order.class).add(Restrictions.eq("externalIdentifier", identifier)).setCacheable(true).list();   
      } finally {
         session.close();   
      }
   }
   
   public void add(Order order) {
      Session session = sessionFactory.openSession();
      Transaction trans = session.beginTransaction();
      try {
         trans.begin();
         session.save(order);
         trans.commit();
      } finally {
         session.close();
      }
   }
}


Code:
package com.jc.test;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class TestRunner {

   @Test
   public void testDodginess() {
      OrderBook orderBook = new OrderBook();
      Order order = new Order(new ExternalSystemOrderIdentifier("SomeSystem", 1l), "DE0009542977", 3000, 15.2);
      orderBook.add(order);
      assertEquals(1, orderBook.find(order.getExternalIdentifier()).size());
   }
}


Code:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
   <session-factory>
      <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
      <property name="connection.url">...</property>
      <property name="connection.username">...</property>
      <property name="connection.password">...</property>
      <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
      <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
      <property name="hibernate.dbcp.minIdle">10</property>
      <property name="hibernate.dbcp.maxIdle">10</property>
      <property name="hibernate.dbcp.initialSize">10</property>
      <property name="hibernate.dbcp.maxActive">10</property>
      <property name="hibernate.jdbc.batch_size">250</property>
      
      <property name="hibernate.cache.use_second_level_cache">true</property>
      <property name="hibernate.cache.use_query_cache">true</property>
      <property name="hibernate.cache.use_structured_entries">true</property>
      <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
      <property name="hibernate.generate_statistics">true</property>
      
      <property name="hibernate.dbcp.poolPreparedStatements">true</property>
      <property name="hibernate.dbcp.maxOpenPreparedStatements">10</property>
      <property name="hibernate.show_sql">false</property>
      <property name="hibernate.hbm2ddl.auto">create-drop</property>

      <mapping class="com.jc.test.Order" />

   </session-factory>
</hibernate-configuration>


Top
 Profile  
 
 Post subject: Re: PropertyAccessException when using Query Cache
PostPosted: Thu Jul 02, 2009 11:45 am 
Newbie

Joined: Mon Oct 20, 2008 6:26 pm
Posts: 3
So it looks to me like this may be a bug in QueryKey, which has changed between the hibernate 3.2.6 and 3.3.2.

When the QueryKey is generated its hashcode is generated, which involves calculating the hascodes for each parameter in the query. This is the call to do that:
Code:
positionalParameterTypes[i].getHashCode( positionalParameterValues[i], entityMode )


So it's passing in a value from the positionalParameterValues array, which in my case is an array of two strings (the values for the two fields in the ExternalSystemOrderIdentifier class), NOT an instance of ExternalSystemOrderIdentifier. ComponentType.getHashCode() seems to expect the object passed in to be an instance of the underlying component, i.e. an instance of ExternalSystemOrderIdentifier, as it tries to get the values of the fields reflectively from this object.

Can anyone from the Hibernate team comment on this? I don't want to raise a Jira if it's not a bug and I'm just being stupid...

Thanks,

Jim


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