Add, delete, modify, and query hibernate associated objects ------ query, hibernate ------

Source: Internet
Author: User

Add, delete, modify, and query hibernate associated objects ------ query, hibernate ------

This blog post is the addition, deletion, modification, and query of hibernate-related objects in the previous blog. the settings of this Code have been written in the previous article. Therefore, before reading this article, please move to the previous blog



// Code piece 5

    SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();        Session session = sessionFactory.getCurrentSession();        session.beginTransaction();                    Dream d=new Dream();        d.setDescription("marry glt");                Person p=new Person();        p.setName("dlf");                d.setPerson(p);            session.save(d);        session.save(p);        session.getTransaction().commit();                        session = sessionFactory.getCurrentSession();        session.beginTransaction();        Dream dream=(Dream) session.get(Dream.class, 1);        System.out.println(dream.getPerson().getName()+"  ddddd");        session.getTransaction().commit();    


For Code 5, the SQL statement sent when get dream is
 select        dream0_.id as id0_1_,        dream0_.description as descript2_0_1_,        dream0_.personId as personId0_1_,        person1_.id as id1_0_,        person1_.myname as myname1_0_    from        Dream dream0_    left outer join        Person person1_            on dream0_.personId=person1_.id    where        dream0_.id=?


In other words, when we get dream, we also get the corresponding person.
Three Problems
1. When Code 5 is executed, the cascade of manytoone of dream has been removed.
2. If you put Dream dream = (Dream) session. get (Dream. class, 1); in the same session as the statement of the previously saved object, the SQL statement sent is update. However, System. out. println (dream. getPerson (). getName () + "ddddd"); can still enter the name of person.

We can draw a rule
In the case of multiple-to-one and one-to-multiple operations, when we read multiple parties, one party will also be read by default. (This rule is irrelevant to cascade)
In turn, if I read one, will I automatically read more?
Let's look at the code
// Code 6 public void testGetPerson () {Session s = sessionFactory. getCurrentSession (); s. beginTransaction (); Person p = (Person) s. get (Person. class, 2); s. getTransaction (). commit ();}
At this time, the SQL statement it sends is:
    select        person0_.id as id1_0_,        person0_.myname as myname1_0_    from        Person person0_    where        person0_.id=?
Did not take the initiative to get the dream corresponding to the person.
What if I want to get dream?
Another parameter in the hibernate management relationship is fetch. It determines whether to read another related object when reading an object.
By reading the api documentation, we know that the fetch value is of the fetchtype type. Fetchtype is an Enum type.
Available values: LAZY and EAGER.

What do these two values mean?
In a guess, we all know that eager actively acquires the data of the associated object, and lazy does not obtain the data.
I can only say that it is probably correct.
Let's look at the code
Modify the onetoworkflow attribute in Person.
    @OneToMany(mappedBy="person",fetch=FetchType.EAGER)    public Set<Dream> getDreams() {        return dreams;    }
Run Code 6 again. The SQL statement is:
 select        person0_.id as id1_1_,        person0_.myname as myname1_1_,        dreams1_.personId as personId3_,        dreams1_.id as id3_,        dreams1_.id as id0_0_,        dreams1_.description as descript2_0_0_,        dreams1_.personId as personId0_0_    from        Person person0_    left outer join        Dream dreams1_            on person0_.id=dreams1_.personId    where        person0_.id=?
We can know that if we want to obtain more than one party at the same time, we will add fetch = feachType. eager to one party.
Then we can guess from the previous Code
By default
The fetch of the first party is lazy.
The fetch of the other party is eager.
Modify the association relationship with eager: hibernate sends the associated SQL
Use lazy to modify the link: hibernate does not ActiveAssociation SQL
Note: what I mentioned above is to use lazy to modify associations: hibernate will not send associated SQL statements.
Why is it proactive? Take a look at the following code
Let's change Code 6.
// Code 7 public void testGetPerson () {Session s = sessionFactory. getCurrentSession (); s. beginTransaction (); Person p = (Person) s. get (Person. class, 2); System. out. println (p. getDreams (). size (); s. getTransaction (). commit ();}
In this case, the fetch value of person is not set. (Keep the default lazy)
The SQL statement is:
Hibernate:    select        person0_.id as id1_0_,        person0_.myname as myname1_0_    from        Person person0_    where        person0_.id=?Hibernate:    select        dreams0_.personId as personId1_,        dreams0_.id as id1_,        dreams0_.id as id0_0_,        dreams0_.description as descript2_0_0_,        dreams0_.personId as personId0_0_    from        Dream dreams0_    where        dreams0_.personId=?
At this point, we can draw a conclusion that, if we only obtain the "one" side in the session, hibernate will not retrieve the other side by default; but if it is in the session, access the data of the "many" side in "1" (that is, access the dream in person) obtained ). The associated SQL statement is sent.

As a result, there is an embarrassing thing.
No matter whether I set fetch = FetchType. eager on the one side, it is okay for me to obtain more than one side in the session.
At this time, it is better not to set fetch = FetchType. what about the eager? Sometimes, I do not need to obtain more than one party. If one party is set to eager, it is not necessary to query a lot of useless data.

Let's look at another example:
// Code 8 public void testGetPerson () {testSavePerson (); Session s = sessionFactory. getCurrentSession (); s. beginTransaction (); Person p = (Person) s. get (Person. class, 2); s. getTransaction (). commit (); System. out. println (p. getDreams (). size ());}
It is to put the code that gets more data from that party out of the session.
If there is fetch = FetchType. eager on the person side, everything is OK.
On-screen output:
Hibernate: select person0 _. id as id1_1 _, person0 _. myname as myname1_1 _, dreams1 _. personId as personId3 _, dreams1 _. id as id3 _, dreams1 _. id as id0_0 _, dreams1 _. description as descript2_0_0 _, dreams1 _. personId as personId0_0 _ from Person person0 _ left outer join Dream dreams1 _ on person0 _. id = dreams1 _. personId where person0 _. id =? 2 // the size of dream is 2
If I remove fetch = FetchType. eager and run code 8, an error is returned:
<span style="color:#FF0000;">failed to lazily initialize a collection of role: com.bjsxt.hibernate.Person.dreams, no session or session was closed</span>
It is clear that the session has been closed.
Why?
We know that from person to dream is one-to-many, and by default, one-to-many fetch is lazy.
That is to say, normally, pseron won't be used again.
Note that the SQL statement sent by code 7 is two.
Now I want to get more commands and run them out of the sesssion. That is to say, if I run the SQL statement in the database after the session is closed, I will definitely report an error.
Let's try again:
// Code 9 public void testGetPerson () {testSavePerson (); Session s = sessionFactory. getCurrentSession (); s. beginTransaction (); Person p = (Person) s. get (Person. class, 2); s. getTransaction (). commit (); System. out. println (p. getDreams (). size (); s. getTransaction (). commit ();}
At this time, the fetch of person is still the default lazy.
Will an error be reported? Try it by yourself.


Hibernate is still troublesome for getting objects. I think the best way is to keep the default value. If there is a problem, check the api documentation or other materials.

Now, why should I write this blog? The best way is to keep the default value.

Because:

Qi Wei of the world, strange and extraordinary view, often lies in the danger of far, and the people of the unknown, so do not have to do.





Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.