In ssh, Hibernate is lazy loaded, session problems are learned and understood, and sshhibernate

Source: Internet
Author: User

In ssh, Hibernate is lazy loaded, session problems are learned and understood, and sshhibernate

 

The following describes how to obtain a session in this project:

Public Session getCurrentSession () {// add, delete, and modify sessions. The transaction must be enabled (Required, that is, propagation = "REQUIRED"); otherwise, return sessionFactory cannot be obtained. getCurrentSession ();} public Session getQueryCurrentSession () {// The session used for query. The generated session has no transactions. Return sessionFactory. openSession ();}

 

Problem 1 Description:

The relationship between Component and Arch is many-to-many. James needs to display the Component record on the page, and then shows that there is a record that a is repeated. After some troubleshooting, it is found that record a corresponds to two

Record B and c. That is, because the relationship between Component and Arch is many-to-many, there are two a pairs in the intermediate table that correspond to different B and c. So why are two duplicate a records displayed on the page only when querying Component? Original

Yes. In this project, lazy loading is disabled, and loading now is enabled, and James uses QBC Query when querying Component.

1. What is lazy loading (delayed loading )? What is loading now?

Data can be obtained only when needed. No matter whether the data is used, you do not need to obtain all the data in a one-time query. Loading immediately may result in a waste of resources and low query efficiency.

2. What is QBC query?

QBC, that is, Query By Criteria, is a Query method provided By Hibernate. It does not need to write hql statements and is directly implemented using the method. The usage and steps of QBC are omitted, use the following configuration to print data on the console:

The corresponding SQL statement to observe.

<prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">true</prop>

Some SQL statements printed on the console show that as long as the associations are configured in the object class for QBC queries, left outer join queries are performed, a aa a. It kills dead cats.

Let me see if the common hql statement does this? Actually different... Actually, the difference between QBC and HQL lies in QBC queries, as long as the associations are configured in the object class for query

During queries, left outer join queries are performed for left outer join queries, while hql queries are performed based on table fields and table join queries are not performed, so it is possible that even if you use loading immediately, it will not be executed during query.

A bug with Repeated Records occurs. a won't think about it now .. But this is also very good, let me understand and learn some of the knowledge that I did not understand .. Ah, haha ....

 

 

Back to the above problem, the reason for record duplication: Because the loading mode is used, when querying, multiple Arch tables with multiple associations are associated with intermediate tables and left outer join queries are performed. Therefore, two duplicate records are displayed.

 

Solve record duplication problem:

1. Use immediate loading. Add deduplicated distinct during query.

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

 

2. Disable loading immediately and use lazy loading (delayed loading). In this way, when querying Component, the left outer join query of the intermediate table will not be performed, and there will be no Repeated Records

 

Question 2 Description:

Method 1 and method 2 can solve the problem. However, if method 2 is used, another problem occurs. Method 2 can solve the problem that James repeats, but Feng Jie has another problem.

The Component queried by the Component id is the Session obtained by the openSession () used in the dao layer, that is, the session has been closed in the dao layer, and now it is used for lazy loading, so Feng Jie is in the action table

The current layer cannot get the corresponding Arch set through the Component object. In this case, the no session exception is thrown. After that, if I am a newbie like me, it may be Ruby, so I will introduce it briefly.

Knowledge involved in this project: (it took a day or two to get confused about the knowledge !!!!!!!!, Just superficial understanding ....)

 

3. How do I obtain a session?

1. Open a new session directly. You need to manually close it.

2. getCurrentSession (): Get the current session. If the session does not exist, open a new one. Otherwise, get the existing session. You do not need to manually close the service and submit it to spring for management. When a service-layer transaction is

After the submission is complete, the session is automatically closed.

 

4. Why should I automatically disable the added, deleted, modified, and obtained sessions on the service layer?

You will understand the following hibernate transaction commit process:

.....Session session=sf.openSession();Transaction tx=session.beginTransaction();.....tx.commit();s.close();

1. Create a session instance

2. Use session to create a Transaction instance and start a Transaction.

3. Use the session method for persistent operations. Persists the object to the database.

4. Submit the operation result and end the transaction. After the object persistence operation is completed, you must submit the transaction.

5. Close the session and disconnect from the database.

After knowing the transaction commit process, we can understand why the project requires the getCurrentSession () and openSession () operations for addition, deletion, and modification operations (). Because the addition, deletion, and modification require transaction operations, the transaction is

The session can be closed only after the service layer and the transaction is committed. Therefore, you cannot immediately close the session on the dao layer, so you do not need openSession (). OpenSession (),

In this case, you do not need to start the transaction during the query to avoid wasting resources. You can directly close the session at the dao layer without affecting the transaction. However, if the problem arises, we can only use

That is, loading, rather than using delayed loading, because the query operations are all disabled at the dao layer, in the service layer or performance layer, you cannot obtain the set attributes of many-to-many relationships based on objects, because

The session is closed at the dao layer.

Therefore, the method to solve the problem of this project can only be loaded immediately.

This can only be used for loading immediately. When there is more data, this will also cause low efficiency. Therefore, it is recommended that you do not do this, but this is also impossible, after all, what is required for query in this project?

OpenSession () and close immediately. But if we leave this project alone, how can we solve the problem of lazy loading? How can we use lazy loading without throwing exceptions?

I personally think that I can only change the method of obtaining the session through the query operation in this project, and change openSession () to getCurrentSession (). Although the current query also requires a transaction (the transaction must be enabled, that is

Propagation = "REQUIRED", otherwise, the session cannot be obtained through getCurrentSession .), However, I do not know who is wasting resources. The efficiency caused by this loading now is compared with that caused by the start of the query transaction.

Source ???????? Next, let's talk about how to solve the problem of lazy loading when the query operation's session Changes to getCurrentSession.

 

To declare this method again, make sure that the dao layer obtains the session from getCurrentSession () to query the object. At this time, the dao layer does not immediately close the sesion and is managed by spring. At the service layer, when the transaction is committed, the session is automatically closed.

 

The location of the project involving lazy loading is generally as follows:

1. In the service layer, you need to use lazy loading.

At this time, the session has not been closed and can be used as needed.

2. In the action of the presentation layer, lazy loading is required.

Because the current session has been closed, It is abnormal to use an object in the presentation layer to obtain the set attributes of many-to-many relationships. So, how to solve it?

Solve the Problem of lazy loading (delayed loading cannot get the associated attribute values of objects:  

1. before the session is closed, the data to be obtained in the business layer is forcibly initialized, that is, the set attribute to be used for initialization. In this way, the data can be acquired again in the action at the presentation layer, here

There are many ways to force it. Let me talk about the methods I used:

 

2. extend the session lifecycle so that the session will be closed after a response is completed (quest, response.

Specific Method: Configure in web. xml

<! -- Extend the lifecycle of a session: when the association relationship needs to be loaded, it will not be searched when it is not needed. For example, when the Department name is loaded, em. dm. the Association Relation --> <filter-name> openSessionInView </filter-name> <filter-class> org. springframework. orm. hibernate3.support. openSessionInViewFilter </filter-class> </filter> <filter-mapping> <filter-name> openSessionInView </filter-name> <url-pattern>/* </url-pattern> </filter-mapping>

 

 

 

 

 

========================================================== ======================================

I am really tired and tired, although it is still difficult, but that's it. Ah, ah, ah ................

Highlights:

1. Feng Jie now needs to use the corresponding Arch object in the Component Module

Implementation Method: After obtaining the Component through the Component id, get the corresponding Arch set through the Component Object

In the service layer, Component is obtained by id. When using OpenSesssion () to open a session, you must manually close the session at the service layer.

Therefore, the corresponding Arch set cannot be obtained at the action presentation layer, because the loading mode is delayed, and the session is closed again.

How can this problem be solved?

Method 1: Use the immediate loading mode

Method 2: uses the delayed loading mode. In the service layer, getCurrentSession () is used to obtain the session. In this mode, after the transaction is completed

(This query ends and leaves the service layer.) submit the request automatically, and configure spring openSessionInView in web. xml to prolong the session

Lifecycle, so that the session will be closed automatically after a request response (request, response) is completed instead of automatically leaving the service layer,

That is, after this configuration is added, the session can also be used in the action presentation layer. In this case, we can obtain the corresponding Arch object in monetization.

1. session

How to get the session? Two methods

Differences between the two methods

2. Lazy Loading

What is lazy loading? What is the function of lazy loading?

How can I solve the problem of lazy loading in projects?

How can I select loading now and loading lazy?

Problems caused by using immediate loading?

For example, exceptions caused by differences between hql queries and qbc queries

Hql queries do not use association relationship queries to directly use table fields or something.

For qbc query, use hibernate. format_ SQL to print the database query statement on the console. You can see that if the association is configured

The left join query is sent.

Therefore, when qbc is used for queries that have many-to-many relationships, the loading mode is enabled immediately. At this time, a record is duplicated during queries.

Solution: 1. deduplicate distinct

2. Use delayed Loading

So the question is how to use spring to prolong the session life cycle (the session is closed only after the request and response ends) in the action presentation layer or getCurrentSession () to get the session, before the session is closed, initialize and obtain the data to be used.

 

For Tom, right. That's right. It's just me. Ah, Hahahaha... Some business methods will like to be written in the presentation layer. The best thing is to write some methods for processing business logic in the business layer so that the session lifecycle does not need to be extended.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.