Hibernate -- Session, hibernatesession
I. Overview
Session is the main interface that Hibernate provides to applications to manipulate data. It provides basic methods for saving, updating, deleting, and loading Java objects.
Ii. Session cache
1. Introduction
(1) Session has a cache called Hibernate level-1 cache. Objects in the cache are called persistent objects. Each Persistent Object corresponds to a record in the database.
(2) From the Perspective of persistence, Hibernate divides objects into four states: temporary state, persistent state, free state, and delete state.
2. Test Session cache
(1) Preparation
① For the hibernate. cfg. xml file, see the previous article.
② SessionFactory, Session, Transaction
private SessionFactory sessionFactory;private Session session;private Transaction transaction;@Beforepublic void init() { Configuration configuration = new Configuration().configure(); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); session = sessionFactory.openSession(); transaction = session.beginTransaction();}@Afterpublic void destroy() { transaction.commit(); session.close(); sessionFactory.close();}
Note: unit test classes are used for testing. Because it is a test environment and there is no concurrency, a Session object is created.
(2) test
@Testpublic void testSession() { News news = (News) session.get(News.class, 1); System.out.println(news); News news2 = (News) session.get(News.class, 1); System.out.println(news2); System.out.println(news.equals(news2));}
Test results:
Hibernate: select news0_.id as id1_0_0_, news0_.title as title2_0_0_, news0_.author as author3_0_0_, news0_.date as date4_0_0_ from hibernate.news news0_ where news0_.id=?News{id=1, title='Title', author='tom', date=2016-09-28}News{id=1, title='Title', author='tom', date=2016-09-28}true
Note:
During the first query, the reference is assigned to news, and a copy is saved to the Session cache.
During the second query, the select statement is not sent but directly obtained from the Session cache.
3. Manipulate Session cache
(1) flush (): Make the records in the data table consistent with the status of the objects in the Session cache.
① In the commit () method of Transaction, call the flush method of the session before committing the Transaction.
Org. hibernate. engine. transaction. spi. AbstractTransactionImpl # commit
@Overridepublic void commit() throws HibernateException { if ( localStatus != LocalStatus.ACTIVE ) { throw new TransactionException( "Transaction not successfully started" ); } LOG.debug( "committing" ); beforeTransactionCommit(); try { doCommit(); localStatus = LocalStatus.COMMITTED; afterTransactionCompletion( Status.STATUS_COMMITTED ); } catch ( Exception e ) { localStatus = LocalStatus.FAILED_COMMIT; afterTransactionCompletion( Status.STATUS_UNKNOWN ); throw new TransactionException( "commit failed", e ); } finally { invalidate(); afterAfterCompletion(); }}
Org. hibernate. engine. transaction. internal. jdbc. JdbcTransaction # beforeTransactionCommit
protected void beforeTransactionCommit() { this.transactionCoordinator().sendBeforeTransactionCompletionNotifications(this); if(this.isDriver && !this.transactionCoordinator().getTransactionContext().isFlushModeNever()) { this.transactionCoordinator().getTransactionContext().managedFlush(); } if(this.isDriver) { this.transactionCoordinator().getTransactionContext().beforeTransactionCompletion(this); }}
② The SQL statement may be printed, but the transaction will not be committed.
③ The flush () operation may also be performed before a transaction is committed or the flush () method is explicitly called.
- Execute the HQL or QBC query to perform the flush () operation first to obtain the latest records of the data table.
- If the record ID is generated by the auto-increment method used by the database, the INSERT statement will be sent immediately when the save () method is called, because after the save method, the object ID must exist.
(2) refresh (): The SELECT statement is forcibly sent to ensure that the State of the objects in the Session cache is consistent with that of the corresponding records in the data table.
1 @Test2 public void testRefresh() {3 News news = (News) session.get(News.class, 1);4 System.out.println(news);5 session.refresh(news);6 System.out.println(news);7 }
On the 5th line breakpoint, I modified the 'author' field of News in the database and changed it to jerry. Run.
The two prints have the same results.
Hibernate: select news0 _. id as id1_0_0 _, news0 _. title as title2_0_0 _, news0 _. author as author3_0_0 _, news0 _. date as date4_0_0 _ from hibernate. news news0 _ where news0 _. id =? News {id = 1, title = 'title', author = 'Tom ', date = 2016-09-28} Hibernate: select news0 _. id as id1_0_0 _, news0 _. title as title2_0_0 _, news0 _. author as author3_0_0 _, news0 _. date as date4_0_0 _ from hibernate. news news0 _ where news0 _. id =? News {id = 1, title = 'title', author = 'Tom ', date =}View Code
Cause: the database isolation level. The default isolation level of Mysql is repeatable read.
You can explicitly set the isolation level in the Hibernate configuration file. Each isolation level corresponds to an integer:
1. READ UNCOMMITED
2. READ COMMITED
4. REPEATABLE READ
8. SERIALIZEABLE
Hibernate sets the transaction isolation level by specifying the Hibernate. connection. isolation attribute for the hibernate ing file.
Printed result after modification:
The two prints have different results.
Hibernate: select news0 _. id as id1_0_0 _, news0 _. title as title2_0_0 _, news0 _. author as author3_0_0 _, news0 _. date as date4_0_0 _ from hibernate. news news0 _ where news0 _. id =? News {id = 1, title = 'title', author = 'Jerry ', date = 2016-09-28} Hibernate: select news0 _. id as id1_0_0 _, news0 _. title as title2_0_0 _, news0 _. author as author3_0_0 _, news0 _. date as date4_0_0 _ from hibernate. news news0 _ where news0 _. id =? News {id = 1, title = 'title', author = 'Tom ', date =}View Code
(3) clear (): clear the cache.
@Testpublic void testClear() { session.get(News.class, 1); session.clear(); session.get(News.class, 1);}
Output result:
Hibernate: select news0 _. id as id1_0_0 _, news0 _. title as title2_0_0 _, news0 _. author as author3_0_0 _, news0 _. date as date4_0_0 _ from hibernate. news news0 _ where news0 _. id =? Hibernate: select news0 _. id as id1_0_0 _, news0 _. title as title2_0_0 _, news0 _. author as author3_0_0 _, news0 _. date as date4_0_0 _ from hibernate. news news0 _ where news0 _. id =?View Code
Iii. Session API
1. transition diagram of four States
(1) Temporary objects
- When the proxy primary key is used, the OID is usually null.
- Not in Session cache
- No corresponding records in the database
(2) Persistence object
- OID is not empty
- In Session cache
- In the cache of the same Session instance, each record in the database table only corresponds to a unique Persistent Object.
(3) Free object
- OID is not empty
- Not in Session cache
(4) Delete an object
- No records corresponding to the OID in the database
- No longer in Session cache
2. save ()
(1) converting a temporary object into a Persistent Object
(2) assign an ID to the object
(3) execute an INSERT statement during the flush Cache
(4) The id before the save () method is invalid.
(5) the ID of the Persistent object cannot be changed. Because Hibernate maintains its correspondence with database-related records through the persistence object OID.
* Difference between persist () and save ()
When the save () method is executed for an object whose OID is not Null, the object is saved to the database as a new OID, and persist () throws an exception.
3. get ()/load ()
(1) you can load a persistent object from the database according to the OID.
(2) objects are loaded immediately when get () is executed. Run load (). If this object is not used, a proxy object is returned instead.
(3) get () indicates instant retrieval, while load () indicates delayed retrieval.
(4) If no corresponding record exists in the data table, the Session is not closed. Get () returns null, and load () throws an exception when using the returned object.
(5) load () may throw LozyInitizationException: The Session has been closed before the proxy object needs to be initialized.
@Testpublic void testLoad() { News news = (News) session.load(News.class, 1); session.close(); System.out.println(news);}
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
4. update ()
(1) convert a free object to a persistent object and execute an update statement.
(2) If you update a persistent object, you do not need to call the update () method explicitly. When calling the commit () method of Transaction, the flush () method of the session is executed first.
(3) Note
- The UPADATE statement is sent no matter whether the free object to be updated is consistent with the record of the data table. How can I send an UPDATE statement only when they are inconsistent? In the class node of the entity. hbm. xml file, set select-before-update = true (default value: false ). Usually, you do not need to set it. Pay attention to it when working with the trigger.
- If no corresponding record exists in the data table but the update () method is still called, an exception is thrown.
- When the update () method is associated with a free object, an exception is thrown if a persistence object with the same OID already exists in the Session cache. Because there cannot be two objects with the same OID in the Session cache.
5. saveOrUpdate ()
(1) Functions of the save () and update () methods are included.
(2) Whether the object is a free object or a temporary object is determined based on the OID of the object. If it is null, save () is executed. If it is not null, it is determined to be a free object and update () is executed ().
(3) If the OID is not null, but there is no corresponding record in the data, an exception is thrown.
(4) understand: the object whose OID value is equal to the unsaved-value Attribute value of id is also considered as a free object.
6. delete ()
(1) You can delete a free object or a persistent object.
(2) As long as the OID corresponds to a record in the data table, the delete operation is ready. If the OID does not have a corresponding record in the data table, an exception is thrown.
(3) After executing delete (), you can still obtain the OID of the object to prevent other persistent operations on the object. You can set hibernate. use_identifier_rollback to true in the hibernate configuration file,
After deleting an object, set its OID value to null.
7. evict ()
Removes the specified persistent object from the session cache.
8. Call the Stored Procedure
@ Testpublic void testWork () {session. doWork (new Work () {@ Override public void execute (Connection connection) throws SQLException {System. out. println (connection); // call the Stored Procedure }});}
Iv. Summary
This section describes Hibernate's level-1 cache, including how to manipulate Session caching, conversion between four states, and Session API Based on Session caching and four States.