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