Hibernate cascade operation and loading mechanism (II) CASCADE and Fetch

Source: Internet
Author: User

The previous article introduced the cascade operation of Hibernate persistence object, this article introduces the cascade operation when reading.

Or use the previous example, a questionnaire has a number of questions, but each problem can only belong to a questionnaire. Let's look at the test case first:

@Test public void Testreadfromquestionnaire () {Session session = Sessionfactory. Getcurrentsession();Session. BeginTransaction();Questionnaire QN = (Questionnaire) session. Load(Questionnaire. Class,1);System. out. println*q,. GetName());Session. Gettransaction(). Commit();for (Question q:qn. Getquestions()) {System. out. println(q. GetName());}     }

read out the ID 1 of the questionnaire, with QN, printed out the name of the questionnaire QN, finally I hope to print out the QN contains what problems, want to print out the problem dry content. But run:

org.hibernate.LazyInitializationException:com.ht.entity.one2manymany2one.bi.fetchcascade.Questionnaire.questionsor session was closed

Error, lazy loading exception, loading the required entities, questionnaire.question This association is not related.
Then the reason for this error is: Hibernate in the processing of a one-to-many relationship, the default is lazy loading, that is, I from a side (questionnaire) side, to read more than the party (Question) side, is not read, this can reduce the database burden, But in case I have this demand, I want to load out a lot of this side how to do it? The code is as follows:

@OneToMany(mappedBy="questionnaire",cascade={CascadeType.ALL},fetch=FetchType.EAGER)    publicgetQuestions() {        return questions;    }

Here, configure the previous property fetch, the type is also enumerated, value eager, here is another value lazy
Erger: Hungry, that is, it will be loaded immediately.
Lazy: The associated object is not loaded
So the one-to-many default is lazy loading, where fetch is configured as eager, we look at the test results:

Hibernate:select questionna0_.ID  asId6_1_, questionna0_.name  asName6_1_, Questionna0_.answers asAnswers6_1_, Questions1_.questionnaireid asQuestion3_3_, questions1_.ID  asId3_, questions1_.ID  asId7_0_, questions1_.name  asname7_0_, Questions1_.questionnaireid asquestion3_7_0_ fromT_questionnaire questionna0_ left outer join T_question questions1_ onquestionna0_.ID=questions1_.questionnaireidwherequestionna0_.ID=? XXX Company3Monthly Exam1, is Java an OOP language? A, is B, not2, which company's work is Java? A, SUN B, MicroSoft

Looking at the SQL statement, a LEFT outer join is used to query the associated object. No problem

There is also an interesting detail, the code is as follows:

    @OneToMany(mappedBy="questionnaire",cascade={CascadeType.ALL})    publicgetQuestions() {        return questions;    }

Here I remove the hunger load and let him revert to the default lazy load, the test case is as follows:

@Test public void Testreadfromquestionnaire () {Session session = Sessionfactory. Getcurrentsession();Session. BeginTransaction();Questionnaire QN = (Questionnaire) session. Load(Questionnaire. Class,1);System. out. println*q,. GetName());for (Question q:qn. Getquestions()) {System. out. println(q. GetName());} session. Gettransaction(). Commit();}

The For loop is a problem in the Loop output questionnaire, and I put the For loop before the transaction commits, and then executes:

Hibernate:select questionna0_.ID  asId6_0_, questionna0_.name  asname6_0_, Questionna0_.answers asanswers6_0_ fromT_questionnaire questionna0_wherequestionna0_.ID=? XXX Company3Monthly Exam Hibernate:select Questions0_.questionnaireid asQuestion3_1_, questions0_.ID  asId1_, questions0_.ID  asId7_0_, questions0_.name  asname7_0_, Questions0_.questionnaireid asquestion3_7_0_ fromT_question questions0_whereQuestions0_.questionnaireid=?1, is Java an OOP language? A, is B, not2, which company's work is Java? A, SUN B, MicroSoft

See, also loaded out, but do not take the associated object, look carefully at the SQL statement found that the first SQL statements executed separately, that is, from the questionnaire query once, and then go to the questionnaire ID to the problem table checked once, so do not cascade.
Then why did the for loop outside can also be found out, the reason is that after the hunger load, the questionnaire object, together with the problem of the subordinate object load to the memory, so the session closed can also read, so the loading mechanism and the difference is here.

Let's read the questionnaire from the question

    @ManyToOne(cascade={CascadeType.ALL})    @JoinColumn(name="questionnaireId")    publicgetQuestionnaire() {        return questionnaire;    }

The fetch attribute is not set here, we look at the test case:

@Test public void Testreadfromquestion () {Session session = Sessionfactory. Getcurrentsession();Session. BeginTransaction();Question q = (Question) session. Load(Question. Class,1);System. out. println(q. GetName());Session. Gettransaction(). Commit();System. out. println(q. GetName());}

To read the question ID 1, print the title and the name of the questionnaire:

Hibernate:select question0_.ID  asId7_0_, question0_.name  asname7_0_, Question0_.questionnaireid asquestion3_7_0_ fromT_question question0_wherequestion0_.ID=? Hibernate:select questionna0_.ID  asId6_1_, questionna0_.name  asName6_1_, Questionna0_.answers asAnswers6_1_, Questions1_.questionnaireid asQuestion3_3_, questions1_.ID  asId3_, questions1_.ID  asId7_0_, questions1_.name  asname7_0_, Questions1_.questionnaireid asquestion3_7_0_ fromT_questionnaire questionna0_ left outer join T_question questions1_ onquestionna0_.ID=questions1_.questionnaireidwherequestionna0_.ID=?1, is Java an OOP language? A, is B, not xxx company3Monthly Exam

No problem, description, many to one of the default load one side is eager, so do not have to do more setup, if you do not want to load a side, then do the following settings:

    @ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.LAZY)    @JoinColumn(name="questionnaireId")    publicgetQuestionnaire() {        return questionnaire;    }

Setting the load mechanism to lazy is OK.

To summarize:
In the relationship of Onetomany (bidirectional):
From 1 to load N on this side, the default is lazy
from N to load 1 on this side, the default is eager

In the cascading and loading mechanism:
Cascade is only responsible for increasing, deleting, and changing the Cascade
If the read requires a cascade load, the Fetch attribute is used.

Hibernate cascade operation and loading mechanism (II) CASCADE and Fetch

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.