1. 程式人生 > >Hibernate Session 4種對象狀態

Hibernate Session 4種對象狀態

otf delegate trac 關閉session rop getimpl pac 方法 堅持不懈

站在持久化的角度。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種對象狀態