使用这些JPA属性
props.put( "hibernate.cache.use_query_cache", "true" ); props.put( "hibernate.cache.use_second_level_cache", "true" ); props.put("hibernate.temp.use_jdbc_metadata_defaults", "false"); props.put( "hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory" ); props.put( "javax.persistence.sharedCache.mode", SharedCacheMode.ALL );
Ehcache对于同一查询效率不高,
问题与QueryCache类的namedParameters.hashCode()函数有关,它为同一查询生成了不同的HashCode!
private int generateHashCode() { int result = 13; result = 37 * result + ( firstRow==null ? 0 : firstRow.hashCode() ); result = 37 * result + ( maxRows==null ? 0 : maxRows.hashCode() ); for ( int i=0; i< positionalParameterValues.length; i++ ) { result = 37 * result + ( positionalParameterValues[i]==null ? 0 : positionalParameterTypes[i].getHashCode( positionalParameterValues[i] ) ); } result = 37 * result + ( namedParameters==null ? 0 : namedParameters.hashCode() ); result = 37 * result + ( filterKeys ==null ? 0 : filterKeys.hashCode() ); result = 37 * result + ( customTransformer==null ? 0 : customTransformer.hashCode() ); result = 37 * result + ( tenantIdentifier==null ? 0 : tenantIdentifier.hashCode() ); result = 37 * result + sqlQueryString.hashCode(); return result; }
与班级有关
org.hibernate.type.AbstractType public int getHashCode(Object x) { return x.hashCode(); }
它将为同一Array对象[01,1]生成一个不同的(新)hachCode!
对于数组,此hashCode方法应该是递归的
递归版本完全正常
类org.hibernate.type.AbstractType
public int getHashCode(Object x) { if (x instanceof Object[]){ int result = 1; for (Object element : (Object[]) x) result = 31 * result + (element == null ? 0 : getHashCode(element)); return result; } return x.hashCode(); }
和
public static boolean arraysEquals(Object[] a, Object[] a2) { if (a==a2) return true; if (a==null || a2==null) return false; int length = a.length; if (a2.length != length) return false; for (int i=0; i<length; i++) { Object o1 = a[i]; Object o2 = a2[i]; if (o1==null){ if (o2!=null) return false; }else{ if (o2==null) return false; if (o1 instanceof Object[]){ if (!(o2 instanceof Object[])) return false; else if (!arraysEquals( (Object[]) o1, (Object[]) o2)) return false; }else if (!o1.equals(o2)) return false; } } return true; } public static boolean equals(final Object x, final Object y) { if (x!=null && x instanceof Object[] && y!=null && y instanceof Object[] ) return arraysEquals((Object[])x, (Object[])y); return x == y || ( x != null && y != null && x.equals( y ) ); }