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层起作用!

 

posted @ 2018-03-13 19:14  Keeloong  阅读(215)  评论(0编辑  收藏  举报