One-to-one correlation of hibernate

Source: Internet
Author: User
Tags class manager generator join

Hibernate's one-to-one correlation is divided into one-to-one correlation based on foreign key and one-to-one correlation relationship based on primary key. In this article, we use the example of Department and department manager to illustrate that one department corresponds to the only department manager, and one department manager corresponds to the only department.
In a one-to-two correlation relationship based on a foreign key, a single end is associated with a primary key at the other end through a field other than a primary key, as shown in the following illustration:
  
   
In a one-to-one correlation relationship based on the primary key, one end directly associates the primary key at the other end through the primary key, and generates its own primary key through the primary key at the other end, as shown in the following illustration:
  
   
Detailed instructions are described below. One -to-one correlation relationship based on foreign keys

For a foreign key-based 1-1 correlation, the foreign key can be stored at either end, for example, in this case, the foreign key can either be stored at the department end, or can be stored at the manager end, we assume that stored at the department end. At one end of the foreign key that needs to be stored, increase the many-to-one node, and add the unique= "true" property for the Many-to-one node to represent the 1-1 Association, adding the Unique= "true" property later, Different department cannot associate the same manager. At one end of the foreign key, you need to use the one-to-one node and add the property-ref property to that node to specify a field other than the primary key that holds the foreign key at one end as the associated field. The code is as follows, creating two classes first:

public class Department {

    private Integer deptid;
    Private String deptname;

    Private Manager Mgr;

    Getters and Setters
} public

class Manager {

    private Integer Mgrid;
    Private String mgrname;

    Private Department Dept;

    Getters and Setters
}

Map file:
 
Department.hbm.xml

<?xml version= "1.0"?>
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en"
"http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">

Manager.hbm.xml
 

<?xml version= "1.0"?> <! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">  

Run an empty test program that can generate database tables managers and departments:
 

 

The following tests test the save and get operations of the 1-1 Association relationship based on the foreign key:

The save operation for the 1-1 affinity relationship based on the foreign key:

@Test public
    void Testsave () {

        Department Department = new Department ();
        Department.setdeptname ("Dept-bb");

        Manager Manager = new manager ();
        Manager.setmgrname ("Mgr-bb");

        Set Association relationship
        Department.setmgr (manager);
        Manager.setdept (department);

        Save operation
        //recommend saving the object without a foreign key column. This will reduce the UPDATE statement
            Session.save (manager);
            Session.save (department);
    }

This code can insert records normally. As in the N-1 Association, if the object holding the foreign key end is saved, then the object at one end of the foreign Key Association is saved, that is, if Session.save (department) is executed first, then Session.save (manager) is executed; Although the same can be saved correctly, but an extra UPDATE statement is used to maintain the association relationship, it is generally recommended to first insert an object that has no foreign key end, and then insert an object with a foreign key end.
  
A get operation for a 1-1 association relationship based on a foreign key:

 @Test public void Testget () {//1. By default, lazy loading is used for associated properties Department dept = (Departme
        NT) Session.get (Department.class, 1); 

        System.out.println (Dept.getdeptname ()); 2. 
So there is the problem of lazy loading exception.
Session.close ();
Manager mgr = Dept.getmgr (); 
System.out.println (Mgr.getclass ()); 

        System.out.println (Mgr.getmgrname ()); 3.  The connection condition for the query Manager object should be dept.manager_id = mgr.manager_id//And should not be dept.dept_id = mgr.manager_id Manager mgr =
        Dept.getmgr (); 
    System.out.println (Mgr.getmgrname ()); }

As with n-1 affinity, when querying an object that holds one end of a foreign key department, the lazy-loading mechanism, which does not immediately load the object manager at the other end of its association, will not be sent until the SELECT statement is loaded until the manager is used. It is also possible that lazy loading exceptions can occur. The result of the operation is shown in the following figure:
  
It is important to note that when you want to use the Manager object, you are querying the manager object through the left outer connection, the connection condition is dept.manager_id = mgr.manager_id, which is correct, Because we configured the property-ref= "Mgr" in the one-to-one node in Manager.hbm.xml, specify the department field of the associated fields Mgr. If the Property-ref property is not set, then the default associated field is Department ID fields, for example, we remove the property-ref= "Mgr" setting, run the Testget () method, The following SQL statement is printed (the connection condition is dept.dept_id = mgr.manager_id), which is clearly not in demand.
  
  
There is also a point of note, that is, when the first query does not hold the foreign key at one end of the object, that is, the manager, because it is not set the foreign key associated to the department, so will use the left OUTER join query, and query out the other end of the object, namely department, and has completed the initialization. As shown below:

@Test public
    void TestGet2 () {
        //When querying an entity object that does not have a foreign key, the left OUTER join query is queried for its associated object
        //and has been initialized. 
        Manager mgr = (manager) Session.get (Manager.class, 1);

        The initialization of the Department object
        System.out.println (Mgr.getmgrname ()) 
        has been completed before executing the following code. System.out.println (Mgr.getdept (). Getdeptname ()); 
    }

Operation Result:

  
One more thing to note about foreign-key-based relationships is that you cannot use foreign key mappings at both ends as 1-1, for example, the Table Department table and the manager are set with foreign key manager_id and department_id respectively. The problem arises when a manager record is associated with one department record, and this department record is associated to another manager record, as shown in the following figure:
  
   
    One -to-one correlation relationship based on primary key

The 1-1 mapping strategy based on the primary key means that the primary key generator at one end uses the foreign policy, indicating that it generates its own primary key based on the primary key of the "opponent" and cannot generate the primary key independently. The <param> child node specifies which property of the current persisted class to use as the "opposite party." For example:

<generator class= "foreign" >
                <!--property attribute specifies the primary key of which property of the current persisted class is used as the foreign key--
                <param name= " Property ">mgr</param>
            </generator>

One end of the foreign primary key generator policy uses the one-to-one element to map the associated property, and you need to set constrained= "true" in the one-to-one node to specify a FOREIGN KEY constraint for the primary key of the database table that corresponds to the current persisted class. Refers to the primary key of the database table that corresponds to the associated object (that is, the "opposite party"). The other end also maps the association relationship using the one-to-one node.
Here we still test with the example of department and manager, starting with a new two class:

public class Department {

    private Integer deptid;
    Private String deptname;

    Private Manager Mgr;

    Getters and Setters
} public

class Manager {

    private Integer Mgrid;
    Private String mgrname;

    Private Department Dept;

    Getters and Setters
}

Map file:
 
Department.hbm.xml

<?xml version= "1.0"?> <! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">  

Manager.hbm.xml

<?xml version= "1.0"?>
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en"
"http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">

The resulting database table is as follows:
 
Managers

Departments


As you can see, table departments is associated with table managers based on the primary key dept_id.
 
The Save and Get methods are tested below:

The save operation for the 1-1 affinity relationship based on the primary key:

@Test public
    void Testsave () {

        Department Department = new Department ();
        Department.setdeptname ("Dept-aa");

        Manager Manager = new manager ();
        Manager.setmgrname ("Mgr-aa");

        Set Association relationship
        Manager.setdept (department);
        Department.setmgr (manager);

        Save Operation
        //First insert which will not have redundant UPDATE
        session.save (department);
        Session.save (manager);

    }

Unlike before, whether Session.save (department) is executed first, or Session.save (manager), the effect is the same, there are only two INSERT statements, there is no UPDATE statement, The insert into managers is executed first, followed by insert into departments, as shown below:
  
  
This is because, now that the department is associated with the manager based on the primary key, the primary key cannot be set to NULL as a foreign key and then update modified, so no matter which statement is placed in front of it, it will wait until the manager record is inserted. Insert the department record again.
  
A get operation for the 1-1 association relationship based on the primary key:

@Test public
    void Testget () {
        //1. By default, lazy loading
        Department dept = (Department) session.get is used for association properties ( Department.class, 1);
        System.out.println (Dept.getdeptname ()); 

        2. So there is the problem of lazy loading exception. 
        Manager mgr = Dept.getmgr ();
        System.out.println (Mgr.getmgrname ()); 
    }

    @Test public
    void TestGet2 () {
        //When querying an entity object that does not have a foreign key, the left OUTER join query is queried for its associated object
        //and has been initialized. 
        Manager mgr = (manager) Session.get (Manager.class, 1);
        /*system.out.println (Mgr.getmgrname ()); 
        System.out.println (Mgr.getdept (). Getdeptname ()); */
    }

Based on the primary key 1-1 and the foreign key based on 1-1 is very similar, in the query department using lazy loading mechanism, may throw lazy loading exception, in the query manager will use the left outer connection, but the difference is that We did not set the Property-ref property in the one-to-one node of the Manager.hbm.xml file, that is, the field of the associated manager in the default department is the ID of department, which is what we want in the 1-1 relationship based on the primary key, so we can see , the connection condition for the left outer connection is dept.dept_id = mgr.manager_id:
  

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.