hibernate 创建一对一唯一外键映射的问题
1.创建映射并执行后发现进行级联操作的时候并没有得到想要的结果!
检查数据库后发现数据的表中没有创建外键约束;
原因:一对一的映射在创建的时候必须要重新创建表,否则没有办法简历外键约束!
解决办法:删除数据库中对应的两个表,并对bean.xml中的hibernate进行修改;
<prop key="hibernate.hbm2ddl.auto">create</prop>
2.级联删除出现异常
TestSSH.testBA testBA(com.ch.test.TestSSH) org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions at org.hibernate.proxy.AbstractLazyInitializer.setSession(AbstractLazyInitializer.java:126) at org.hibernate.engine.StatefulPersistenceContext.reassociateProxy(StatefulPersistenceContext.java:573) at org.hibernate.engine.StatefulPersistenceContext.reassociateIfUninitializedProxy(StatefulPersistenceContext.java:533) at org.hibernate.event.def.ProxyVisitor.processEntity(ProxyVisitor.java:50) at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:125) at org.hibernate.event.def.AbstractVisitor.processValue(AbstractVisitor.java:83) at org.hibernate.event.def.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:77) at org.hibernate.event.def.AbstractVisitor.process(AbstractVisitor.java:144) at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:122) at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:965) at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:948) at org.hibernate.engine.CascadingAction$1.cascade(CascadingAction.java:145) at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392) at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335) at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204) at org.hibernate.engine.Cascade.cascade(Cascade.java:161) at org.hibernate.event.def.DefaultDeleteEventListener.cascadeBeforeDelete(DefaultDeleteEventListener.java:328) at org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:267) at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:162) at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:73) at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:956) at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:934) at com.ch.dao.MainDao.delete(MainDao.java:29) at com.ch.test.TestSSH.testBA(TestSSH.java:86) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
原因:刚开始我觉得是没有进行事务的提交出现了问题,对spring的事务管理进行了验证,发现我在进行service层的操作时,事务并没有提交;
在百度好久后发现这哥们说的太对了---------http://blog.sina.com.cn/s/blog_53a73e790102xer5.html
首先说一下hibernate中创建用来连接数据库的Session,有两种方式。 1.通过Spring的SessionFactory的getCurrentSession的方法创建Session 。 2.通过Spring的SessionFactory的OpenSession的方法创建Session。 getCurrentSession 创建的Session会绑定到当前线程中去,commit或rollback后会,自动关闭Session。 OpenSession 重新开启一个线程创建Session,需要手动关闭Session,如果不关闭将导致session关联的数据库连接无法释放,最后资源耗尽而使程序当掉。
解决:我更改了session的创建方式,改为
Session session=sessionFactory.getCurrentSession();
问题解决了,级联操作可以进行了!!!!
3.出现异常
TestSSH.testMA testMA(com.ch.test.TestSSH) org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:64) at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:685) at com.ch.dao.MainDao.findById(MainDao.java:49) at com.ch.test.TestSSH.testMA(TestSSH.java:140) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
getCurrentSession方法在使用的时候必须使用事务提交!
spring的事务管理,是面向方法的粗粒度的,无法在Dao层起作用!