背景:我们的项目团队正在使用Hibernate的dom4j实体模式为多个客户端应用程序生成SOAP响应。传递的数据量很大,响应时间也是一个问题。我们可以通过使用Hibernate查询缓存和/或二级缓存来显着减少SQL调用的数量。由于我们系统的体系结构,第一级缓存(会话)级别机制不会像SessionFactory上的查询缓存一样工作,从而提高性能。
问题:基本问题是Hibernate的DOM4J实体模式是否与Query缓存兼容。查询结果将被放入查询缓存中。但是,当执行query.list()
方法并找到匹配的缓存查询时,将引发以下异常:
由引起:
java.lang.ClassCastException: org.dom4j.tree.DefaultElement cannot be cast to java.math.BigDecimal
at org.hibernate.type.descriptor.java.BigDecimalTypeDescriptor.extractHashCode(BigDecimalTypeDescriptor.java:36)
at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:197)
at org.hibernate.type.AbstractStandardBasicType.getHashCode(AbstractStandardBasicType.java:192)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:126)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:70)
at org.hibernate.type.ManyToOneType.scheduleBatchLoadIfNeeded(ManyToOneType.java:160)
at org.hibernate.type.ManyToOneType.beforeAssemble(ManyToOneType.java:246)
at org.hibernate.cache.StandardQueryCache.get(StandardQueryCache.java:143)
at org.hibernate.loader.Loader.getResultFromQueryCache(Loader.java:2361)
at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2309)
at org.hibernate.loader.Loader.list(Loader.java:2268)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:452)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:363)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1268)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
我们的环境是Core-Spring / Hibernate ......
在我们的spring-hibernate会话工厂配置中,使用以下配置:
<prop key= "hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
<prop key= "hibernate.cache.region.factory_class"> net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.query.factory_class"> org.hibernate.cache.StandardQueryCacheFactory</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
初步分析:我的直觉是Hibernate的“实验性”DOM4J实体模式与查询和实体缓存不兼容。同样重要的是要注意我们的Hibernate hbm.xml映射文件使用动态映射。也就是说,映射文件没有Class引用;相反,他们有实体参考。因此,直接生成XML响应而不填充类的对象。
对于这件事的任何帮助,我将非常感激。
答案 0 :(得分:0)
所以,经过多次尝试,我发现了问题。
上面的初步分析是关键。当代码在动态映射模式下生成XML时,ehcache水合机制不起作用。解决问题的方法是创建一个类文件来支持hibernate映射。也就是说,当你使用一个名称属性指向一个类的hibernate映射(hbm.xml)文件时,一切都很好。 Hibernate可以对类进行水合,然后在dom4j实体模式下生成XML。
我在class标签中使用了enity-name属性。我的代码试图直接补充XML。如上所述,这失败了。
所以,我希望这个解决方案有一段时间。