Hibernate Session 4种对象状态
Posted 大-雄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate Session 4种对象状态相关的知识,希望对你有一定的参考价值。
站在持久化的角度。Hibernate把对象分为4中状态。 临时状态。 持久化状态。游离状态。删除状态。
1:Save()方法:
//这个是验证:1:save方法使临时对象------>变成持久化对象。
2:为对象分配ID。
3:flush缓存时发送insert语句。
@org.junit.Test public void testSave(){ News news=new News(); news.setTitle("AA"); news.setAuthor("aa"); news.setDate(new Date(0)); System.out.println("save保存前打印:"+news); session.save(news); System.out.println("save保存后打印:"+news); }
//这个是验证:ID在save方法前保存无效。
1 @org.junit.Test 2 public void testSave(){ 3 News news=new News(); 4 news.setTitle("BB"); 5 news.setAuthor("bb"); 6 news.setDate(new Date(0)); 7 news.setId(100); 8 System.out.println("save保存前打印:"+news); 9 session.save(news); 10 System.out.println("save保存后打印:"+news); 11 }
//这是验证 持久化对象的ID不能进行修改。
1 @org.junit.Test 2 public void testSave(){ 3 News news=new News(); 4 news.setTitle("BB"); 5 news.setAuthor("bb"); 6 news.setDate(new Date(0)); 7 System.out.println("save保存前打印:"+news); 8 session.save(news); 9 news.setId(4); 10 System.out.println("save保存后打印:"+news); 11 }
org.hibernate.exception.ConstraintViolationException: could not execute statement
ConstraintViolationException 违反唯一约束条件
constraint 英 [kənˈstreɪnt] n. 约束; 限制; 强制
violation 英 [ˌvaɪə\'leɪʃn] n. 违反,妨碍,侵犯; 违犯,违背; [体] 违例,犯规; 强奸,亵渎,污辱 at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74) at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125) at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136) at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96) at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2975) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3480) at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81) at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377) at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:214) at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194) at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:178) at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321) at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286) at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192) at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206) at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191) at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49) at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90) at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:764) at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756) at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752) at com.hibernate.helloworld.Test.testSave(Test.java:54) 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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 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) Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry \'BB\' for key \'UK_duq2gjdo5k53otrakypw0888b\' 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:1015) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3515) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3447) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1951) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2101) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2554) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1761) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2046) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1964) at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1949) at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133) ... 47 more org.hibernate.AssertionFailure: null id in com.hibernate.helloworld.News entry (don\'t flush the Session after an exception occurs) at org.hibernate.event.internal.DefaultFlushEntityEventListener.checkId(DefaultFlushEntityEventListener.java:79) at org.hibernate.event.internal.DefaultFlushEntityEventListener.getValues(DefaultFlushEntityEventListener.java:194) at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:156) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:228) at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:100) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404) at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101) at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175) at com.hibernate.helloworld.Test.destroy(Test.java:34) 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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 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)
2:persist():和save一样。只有一个区别:
在persist()方法前设置ID会报错。如果对象有ID。不能执行insert。而是会抛出异常
@org.junit.Test public void testPersist(){ News news=new News(); news.setTitle("CC"); news.setAuthor("cc"); news.setDate(new Date(0)); news.setId(4); System.out.println("save保存前打印:"+news); session.persist(news); System.out.println("save保存后打印:"+news); }
org.hibernate.PersistentObjectException: detached entity passed to persist: com.hibernate.helloworld.News
persistent 英 [pəˈsɪstənt] adj. 持续的; 持久的; 坚持不懈的; 坚持不渝
detached 英 [dɪˈtætʃt] adj. 超然的; 分离的,分开的; 公平的; 分遣的,派遣的
v. 派遣; 分开(detach的过去式和过去分词); 分离,退出
persist v. 坚持; 存留; 固执; 继续存在 at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141) at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:78) at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:853) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:827) at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:831) at com.hibernate.helloworld.Test.testPersist(Test.java:55) 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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 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)
3:get()和load()方法的区别:
1):get会立即加载对象。返回的是类本身。
load不会。只是去使用的时候才会执行查询语句。返回的是一个代理对象。代理对象就是别人让你做一件事。先答应下来。然后他需要的时候去帮他做。
get立即检索。load延迟检索。
@org.junit.Test public void testGet(){ News news =(News) session.get(News.class, 1); System.out.println(news); } @org.junit.Test public void testLoad(){ News news =(News) session.load(News.class, 1); System.out.println(news); }
@org.junit.Test public void testGet(){ News news =(News) session.get(News.class, 1); // System.out.println(news); } @org.junit.Test public void testLoad(){ News news =(News) session.load(News.class, 1); // System.out.println(news); }
get方法会有查询语句。load方法不会执行查询语句。
打印这个对象到底是什么?
@org.junit.Test public void testGet(){ News news =(News) session.get(News.class, 1); System.out.println(news.getClass()); // System.out.println(news); } @org.junit.Test public void testLoad(){ News news =(News) session.load(News.class, 1); System.out.println(news.getClass()); // System.out.println(news); }
get: 类自己本身。
load:是一个代理类
2):load可能抛出一个 LazyInitializationException 异常: could not initialize proxy - no Session
因为get是先加载。然后会打印出来。 load是答应了别人。别人需要了去帮他做的时候。发现session已经关闭了。然后抛出一个懒加载异常。
@org.junit.Test public void testGet(){ News news =(News) session.get(News.class, 1); session.close(); System.out.println(news); } @org.junit.Test public void testLoad(){ News news =(News) session.load(News.class, 1); session.close(); System.out.println(news); }
get会打印出来。load抛出一个懒加载异常。
1 org.hibernate.LazyInitializationException: could not initialize proxy - no Session 2 at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164) 3 at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285) 4 at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) 5 at com.hibernate.helloworld.News_$$_javassist_0.toString(News_$$_javassist_0.java) 6 at java.lang.String.valueOf(String.java:2827) 7 at java.io.PrintStream.println(PrintStream.java:771) 8 at com.hibernate.helloworld.Test.testLoad(Test.java:80) 9 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 10 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 11 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 12 at java.lang.reflect.Method.invoke(Method.java:597) 13 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 14 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 15 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 16 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 17 at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 18 at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 19 at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 20 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 21 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 22 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 23 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 24 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 25 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 26 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 27 at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 28 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 29 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 30 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 31 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 32 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 33 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
3):查询数据库中没有的对象。get返回一个null。load会抛出一个ObjectNotFoundException 异常
1 @org.junit.Test 2 public void testGet(){ 3 News news =(News) session.get(News.class, 10); 4 System.out.println(news); 5 } 6 @org.junit.Test 7 public void testLoad(){ 8 News news =(News) session.load(News.class, 10); 9 System.out.println(news); 10 }
1 org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.hibernate.helloworld.News#10] 2 at org.hibernate.internal.SessionFactoryImpl$1$1.handleEntityNotFound(SessionFactoryImpl.java:244) 3 at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:261) 4 at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:175) 5 at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285) 6 at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) 7 at com.hibernate.helloworld.News_$$_javassist_0.toString(News_$$_javassist_0.java) 8 at java.lang.String.valueOf(String.java:2827) 9 at java.io.PrintStream.println(PrintStream.java:771) 10 at com.hibernate.helloworld.Test.testLoad(Test.java:78) 11 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 12 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 13 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 14 at java.lang.reflect.Method.invoke(Method.java:597) 15 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 16 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 17 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 18 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 19 at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) 20 at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) 21 at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 22 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 23 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 24 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 25 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 26 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 27 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 28 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 29 at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 30 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 31 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 32 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 33 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 34 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 35 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
4:update()方法:
1):若更新一个持久化对象。不需要显示的调用update方法。因为在调用事务中的commit()方法的时候,先执行session的flush()方法。
这个是验证把游离对象变成一个持久化对象。因为查询出来news对象。有OID。但是session缓存中没有这个对象。所以是游离对象。执行了update对象。session就有这个对象了。
关闭session。重新打开的时候。不会执行update语句。 因为news对象是查询出来了。放在session缓存中。然后关闭了。又重新打开了一个session中。
但是新打开的session中没有news对象。所以修改对象不会执行update。需要显示的调用update方法。
1 @org.junit.Test 2 public void testUpdate(){ 3 News news =(News) session.get(News.class, 1); 4 transaction.commit(); 5 session.close(); 6 7 session=sessionFactory.openSession(); 8 transaction=session.beginTransaction(); 9 10 news.setAuthor("YI"); 11 12 }
1 @org.junit.Test 2 public void testUpdate(){ 3 News news =(News) session.get(News.class, 1); 4 transaction.commit(); 5 session.close(); 6 7 session=sessionFactory.openSession(); 8 transaction=session.beginTransaction(); 9 10 news.setAuthor("YI"); 11 session.update(news); 12 }
但是显示调用update方法。有个小缺点。
无论更新的游离对象和数据表中的记录是否一样。都会执行update语句。Hibernate有个触发器。每执行一个update方法。都会触发一次。影响效率。
可以在.hbm.xml文件中class 节点下 select-before-update="true" 。就不会盲目的触发update语句。但是不常用。
2):若数据表中没有对应的记录。但还调用了update方法。会抛出异常。
1 查询一个news对象。然后修改ID 。抛出StaleObjectStateException 异常 2 @org.junit.Test 3 public void testUpdate(){ 4 News news =(News) session.get(News.class, 1); 5 transaction.commit(); 6 session.close(); 7 8 session=sessionFactory.openSession(); 9 transaction=session.beginTransaction(); 10 11 news.setId(10); 12 session.update(news); 13 }
1 查询一个根本不存在的对象 抛出IllegalArgumentException异常 2 @org.junit.Test 3 public void testUpdate(){ 4 News news =(News) session.get(News.class, 10); 5 transaction.commit(); 6 session.close(); 7 8 session=sessionFactory.openSession(); 9 transaction=session.beginTransaction(); 10 11 // news.setId(10); 12 session.update(news); 13 }
3):当update()方法关联一个游离对象时。如果session的缓存中已经存在相同OID的持久化对象。会抛出异常。因为在Session缓存中不能有两个相同OID的对象。
@org.junit.Test public void testUpdate(){ News news =(News) session.get(News.class, 1); transaction.commit(); session.close(); session=sessionFactory.openSession(); transaction=session.beginTransaction(); News news2 =(News) session.get(News.class, 1); session.update(news); }
4:saveOrUpdate()方法。
5:delete()方法。
只要OID和数据表中一条记录对应。就删除。若OID没有对应的。抛出异常。
1 @org.junit.Test 2 public void testDelete(){ 3 News news =(News) session.get(News.class, 1); 4 session.delete(news); 5 System.out.println(news); 6 }
删除后这个OID还是有值的。删除后OID为空。可以在hibernate.cfg.xml中设置。
<property name="hibernate.use_identifier_rollback">true</property>
删除一个没有的。抛出IllegalArgumentException异常。
java.lang.IllegalArgumentException: attempt to create delete event with null entity at org.hibernate.event.spi.DeleteEvent.<init>(DeleteEvent.java:45) at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:936) at com.hibernate.helloworld.Test.testDelete(Test.java:95) 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.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 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)
6:evict():把一个对象从session缓存中移除。
@org.junit.Test public void testEvict(){ News news1 =(News) session.get(News.class, 1); News news2 =(News) session.get(News.class, 2); news1.setTitle("XX"); news2.setTitle("YY"); session.evict(news1); }
只修改了2.
转载自https://www.cnblogs.com/bulrush/p/7786973.html
以上是关于Hibernate Session 4种对象状态的主要内容,如果未能解决你的问题,请参考以下文章