Regarding the hibernate problem encountered by my colleagues yesterday. It is the most basic thing of hibernate. I understand that many people have encountered this problem and it is very common, but they often become confused when encountering it.
In order to deepen the impression, know what it is and why it is so.
After that, I simply used the original Hibernate framework to do some verification, and opened the execution SQL printout console, and came to the conclusion:
The premise is that in the middle of the same transaction:
1. Use the sql statement, session.createSQLQuery(sql).executeUpdate(); to insert, and the output station will print out the sql insertion statement; then use the sql statement to perform session.createSQLQuery(sql).uniqueResult(); and the SQL query will also be printed. statement, there is no problem and the data can be queried.
2. Use hibernate to encapsulate the operation and use session.save(entity); to insert. The output console does not print out the inserted SQL statement. Then use the session.get(entity,id); method to make a query; it also does not print out the SQL query statement. , but the data can be queried. When the transaction commit statement is executed, the inserted SQL statement is printed out
3. Use hibernate's session.save(entity); to insert, and then use the "HQL" statement to query. The effect is the same as the second point above.
4. Use hibernate's session.save(entity); to insert, but the output console does not print out the inserted SQL statement. Then use the sql statement to perform session.createSQLQuery(sql).uniqueResult(); and the SQL query statement will be printed. A problem occurred, no data could be queried. In this case, use the session.flush() method, execute the flush() method before querying, and the output console will print out the inserted SQL statement. If you query again, you will have data.
After the verification was completed, I checked the information above. Regarding the fourth point, it appeared frequently during the development process. It is very common. I believe many people have encountered it, but many people continue to be confused. This just deepened the impression.
From the printing console SQL, we can see the operation process of a basic hibernate save method:
1. Determine whether the instance to be saved is already in a persistent state, and if not, place it in the cache;
2. Plan an insert sql statement based on the instance to be saved. Note that it is only planned and not executed;
3. The previously planned insert statement is executed when the transaction is committed;
Replace tx.commit() with session.flush. At this time, the control prints out the insert statement, but no new records are added to the database;
The main function of the flush method is to clean the cache and force the database to synchronize with the Hibernate cache to ensure data consistency. Its main action is to send a series of SQL statements to the database and execute these SQL statements, but it will not submit them to the database. The commit method will first call the flush method and then commit the transaction. This is why the record is not inserted into the database when we just call flush, because the updates to the database will not be saved until the transaction is committed. Because the commit method implicitly calls flush, we generally do not call the flush method explicitly.
This is hibernate's flush mechanism. In the process of updating and saving some complex objects, it is necessary to consider whether changes in the order of database operations and whether delayed flushes have an impact on the results of the program. If there is indeed an impact, you can add flush where you need to maintain the order of operations to force Hibernate to flush the operations recorded in the cache into the database. This may not look pretty, but it is very effective.
Question: The session.save method is put into the cache and cannot be found out by SQL directly querying the database.
After the flush() method, the executed SQL will be printed, but it is still not in the database. Direct SQL query can find the data.
1. Where is the entity data stored after flush()? The cache is the same as the save() method, so SQL should not be able to get it.
2. Since the data did not enter the database after the flush method, SQL can be directly queried using session.createSQLQuery(sql) to query. It should be directly checked that it is not the database. What is the place he is querying?