使用Hibernate的二级缓存:EhCache,但是不知道错在哪里?hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration>
<session-factory > <!-- local connection properties -->
<property name="connection.url">jdbc:mysql:///itcastbbs2</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">111111</property>
<!-- property name="connection.pool_size"></property --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property> <property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping resource="cn/itcast/bbs/domain/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration
PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration>
<session-factory > <!-- local connection properties -->
<property name="connection.url">jdbc:mysql:///itcastbbs2</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">111111</property>
<!-- property name="connection.pool_size"></property --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="show_sql">false</property>
<property name="hbm2ddl.auto">update</property> <property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping resource="cn/itcast/bbs/domain/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="D:\job2\cache"/>
<defaultCache maxElementsInMemory="10000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="180"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="60"/>
<cache name="cn.itcast.bbs.domain.User"
maxElementsInMemory="100"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskPersistent="false"/>
</ehcache>User.hbm.xml<?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="cn.itcast.bbs.domain">
<class name="User" table="itcast_user">
<cache usage="read-write" region="cn.itcast.bbs.domain.User"/>
<id name="id" column="id" length="45">
<generator class="uuid"/>
</id>
<property name="loginName" column="loginName" length="128" />
<property name="password" column="password" length="128" />
<property name="email" column="email" length="128"/>
<property name="nickName" column="nickname" length="128"/>
</class>
</hibernate-mapping>
import java.util.List;import javax.annotation.Resource;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import cn.itcast.bbs.domain.User;
import cn.itcast.bbs.service.UserService;public class UserTest {
private static UserService userService;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
try {
ApplicationContext act=new ClassPathXmlApplicationContext("applicationContext.xml");
userService=(UserService)act.getBean("userServiceImpl");
//System.out.println("userService:"+userService);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testSpring(){
User user=userService.getUser("ff80808129e398d90129e398db620001");
System.out.println("userLoginName:"+user.getLoginName());
try {
System.out.println("关闭数据库");
Thread.sleep(1000*15);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("睡眠结束");
user=userService.getUser("ff80808129e398d90129e398db620001");
System.out.println("userLoginName:"+user.getLoginName());
}
}
userLoginName:asdf
关闭数据库
睡眠结束------------------------------说明,缓存中没有第一次查询的数据。
怎样才能在缓存中有数据呢?
或者哪里出了错误呢?
结果在JUnit中报错:org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: JDBC commit failed
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:610)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy10.getUser(Unknown Source)
at cn.test.UserTest.testSpring(UserTest.java:52)
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:597)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.TransactionException: JDBC commit failed
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:130)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:606)
... 30 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during commit(). Transaction resolution unknown.
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:985)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927)
at com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1561)
at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:139)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:115)
... 31 more
错在哪里呢?向各位请教了。
为什么第一次查询的user,会没有缓存呢?
maxElementsInMemory="100"
eternal="true"
overflowToDisk="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
diskPersistent="false"/>
</ehcache>这样试试
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="cn.itcast.bbs.domain.User"
maxElementsInMemory="5000"
eternal="true"
overflowToDisk="false"
/>
</ehcache>
时间上面的设置你可以按照自己的定义,这样试试看行不行
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessAfterInstantiation(CommonAnnotationBeanPostProcessor.java:293)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:957)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:470)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:217)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:729)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:381)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at cn.test.UserTest.setUpBeforeClass(UserTest.java:29)
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:597)
at org.junit.internal.runners.ClassRoadie.runBefores(ClassRoadie.java:49)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:36)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: Error configuring from file:/D:/job2/ItcastBBS2/build/classes/ehcache.xml. Initial cause was Error configuring from input stream. Initial cause was null:13: Element <defaultCache> does not allow attribute "maxElementsOnDisk".
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1336)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:471)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:217)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:427)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:502)
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180)
at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessAfterInstantiation(CommonAnnotationBeanPostProcessor.java:290)
... 29 more
Caused by: net.sf.ehcache.CacheException: Error configuring from file:/D:/job2/ItcastBBS2/build/classes/ehcache.xml. Initial cause was Error configuring from input stream. Initial cause was null:13: Element <defaultCache> does not allow attribute "maxElementsOnDisk".
at net.sf.ehcache.config.ConfigurationFactory.parseConfiguration(ConfigurationFactory.java:95)
at net.sf.ehcache.config.ConfigurationFactory.parseConfiguration(ConfigurationFactory.java:131)
at net.sf.ehcache.CacheManager.parseConfiguration(CacheManager.java:241)
at net.sf.ehcache.CacheManager.init(CacheManager.java:190)
at net.sf.ehcache.CacheManager.<init>(CacheManager.java:183)
at org.hibernate.cache.EhCacheProvider.start(EhCacheProvider.java:124)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:183)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1300)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:816)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:734)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1367)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1333)
... 43 more
问题找到了是在UserServiceImpl.java的public User getUser(String id)上面没有写:
@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
为什么会是这样的?它怎么会影响二级缓存呢?UserServiceImpl.java:
package cn.itcast.bbs.service.impl;import java.util.List;import javax.annotation.Resource;import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;import cn.itcast.bbs.domain.User;import cn.itcast.bbs.service.UserService;@Service("userServiceImpl")
@Transactional
public class UserServiceImpl implements UserService{ @Resource SessionFactory sessionFactory;
@Override
@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
public User getUser(String id) {
return (User)sessionFactory.getCurrentSession().get(User.class,id);
}
}
依然可以是使用二级缓存?那ehcache.xml文件,可以不用存在吗?
你的这两个问题好奇怪!!!!!!!!!!!!!!!!!!!
第一个与spring管理有关系。
第二个,可能使用了jar包的默认配置。
userLoginName:asdf
关闭数据库
睡眠结束
没有缓存内容。
这样声明打开查询缓存还没有用,在查询的时候还必须设值
user=userService.getUser("ff80808129e398d90129e398db620001");
你这个是根据条件查询user所以我猜想你的getUser方法只是这样的
Query query=session.createQuery("***");
如果我猜的没错的话,应该只有上面一句,如果真是这样,是不行的,还必须这样设置,显示地让Query查询的时候使用查询缓存:
query.setCacheable(true);
如果我没猜错的话,你的问题应该出在这里