Bidirectional primary Key Association and bidirectional foreign Key association in the Java Hibernate framework _java

Source: Internet
Author: User
Tags commit generator object model rollback sessions

One, bidirectional primary Key Association
A two-way primary key association is actually a special case of one-way one-to-one primary key associations, except for the <one-to-one> configuration in the mapping file at both ends of the associated object, plus the foreign Foreign Key Association attribute at the primary key end of the primary mapping.
Here also use person and Idcard to discuss, one corresponds to a unique identity card, and an identity card is the only map of a person, so this produces a two-way relationship, person's primary key is also Idcard primary key, is the primary key is also a foreign key, This association becomes a two-way one-to-one mapping, which is shown in the relational model as follows:

The two tables in the diagram use the Primary key association, the person's primary key is the primary key of the idcard, so they form the binding relationship between the foreign keys, and ensure uniqueness, mapping into the object model, into the person class and Idcard class of one-to-one relationship, the following figure:

This one-to-one relationship is also mentioned in the article is the use of <one-to-one> tags, and this one-to-one mapping is two-way, so to two objects at the same time to configure <one-to-one> First look at the Idcard corresponding class code and mapping file code.

1, idcard the corresponding information
Idcard.java class, there is a one-to-one association between the Idcard class and the person class, so add the corresponding person attribute to the Idcard class in order to add the corresponding property to the foreign key in the mapping file and set the corresponding foreign key association class.

Package com.src.hibernate; 
 
public class Idcard { 
   
  //id property 
  private int id; 
  public int getId () {return 
    ID; 
  } 
  public void setId (int id) { 
    this.id = ID; 
  } 
   
  Card number attribute 
  private String Cardno; 
  Public String Getcardno () {return 
    cardno; 
  } 
  public void Setcardno (String cardno) { 
    this.cardno = Cardno; 
  } 
   
  Card number corresponding to the person who is 
  private; 
  Public Person Getperson () {return person 
    ; 
  } 
  public void Setperson (person person) { 
    This.person=person 
  } 
} 

IdCard.hbm.xml mapping file, add the foreign key attribute person to the mapping file, and add the corresponding <one-to-one> tag to force the person class to implement a one-to-one mapping relationship. Finally, the constrained property is set to true in the mapping to ensure that the constraint relationship is enforced.

<?xml version= "1.0"?> 
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" 
"http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd "> 
<!--generated 2014-5-15 23:47:00 by hibernate Tools 3.4.0.cr1--> 
< hibernate-mapping> 
  <class name= "Com.src.hibernate.IdCard" table= "Idcard" > 
    <id name= "id" type= " int "column=" personId "> 
      <generator class=" foreign "> 
        <param name=" Property ">person</ param> 
      </generator> 
    </id> 
     
    <property name= "Cardno" type= "string" column= "Cardno" ></property> 
    <one-to-one name= "Person" constrained= "true" ></one-to-one> 
  </ Class> 
 
 

2, the person corresponding information
Person.java class, in which you add the corresponding Idcard class as a property in addition to the basic attributes, because they are one-to-one, bidirectional associations, so you add the Idcard class in the person class, the same reason the person class attribute is also added to the Idcard class 。

Package com.src.hibernate; 
 
public class Person { 
   
  //id number 
  private int id; 
  public int getId () {return 
    ID; 
  } 
  public void setId (int id) { 
    this.id = ID; 
  } 
   
  Name 
  private String name; 
  Public String GetName () {return 
    name; 
  } 
  public void SetName (String name) { 
    this.name = name; 
  } 
   
  Idcard 
  private Idcard idcard; 
  Public Idcard Getidcard () {return 
    idcard; 
  } 
  public void Setidcard (Idcard idcard) { 
    this.idcard = Idcard; 
  } 
} 

Person.hbm.xml mapping file, the primary key generation strategy in this file has no special requirements because it is related to the Idcard class, its primary key and foreign keys are idcard primary keys, and because it's a pair of relationships, add <one-to-one to the mapping file. > Label to mark.

<?xml version= "1.0"?> 
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" 
"http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd "> 
<!--generated 2014-5-15 23:47:00 by hibernate Tools 3.4.0.cr1--> 
< hibernate-mapping> 
  <class name= "Com.src.hibernate.Person" table= "person" > 
    <id name= "id" type= " int "column=" personId "> 
      <generator class=" native "></generator> 
    </id> 
     
    < Property name= "Name" type= "string" column= "PersonName" ></property> 
  <!-- 
  The one-to-one label indicates how hibernate loads its associated object, which is loaded by default based on the primary key, that is, the value of the relationship field, which loads the associated object based on the primary key to the end 
   --> 
  <one-to-one name= " Idcard "></one-to-one> 
  </class> 
 
 

3. Hibernate mapping File
after the above class and mapping files are configured, the next step is to configure the information in the Hibernate.cfg.xml with the database mapping, and you need to add two profiles to the Hibernate configuration file so that you can find the corresponding build items when you build the corresponding database.

<?xml version= "1.0" encoding= "UTF-8"?> <! DOCTYPE hibernate-configuration Public "-//hibernate/hibernate configuration DTD 3.0//en" "Http://hibernate.sour Ceforge.net/hibernate-configuration-3.0.dtd ">  

4, produce the result
after the configuration is complete, the above content can be generated to the corresponding database, in the database it will be configured to generate the corresponding table structure, in the table has the corresponding foreign key and primary key fields. When you make a table structure, hibernate prints the appropriate SQL statements in the console as follows:

ALTER TABLE Idcard drop FOREIGN key fk806f76abac038cd8 
drop table if exists idcard 
drop table if exists person
   
    create table Idcard (PersonId integer NOT NULL, Cardno varchar (255), primary key (PERSONID)) 
CREATE table person (per Sonid integer NOT NULL auto_increment, PersonName varchar (255), primary key (PERSONID)) 
ALTER TABLE Idcard Add index F K806F76ABAC038CD8 (PERSONID), add constraint FK806F76ABAC038CD8 foreign key (personId) references person (personId) 

   

The resulting table structure is shown in the following illustration:

The PersonID primary key is generated at the same time in both tables, and it is also the corresponding foreign key, which also restricts the same and unique primary keys that constrain both tables.

5. Write Load test
After the table is generated, the table is written and read from the table, the corresponding test class is written, the test adopts unit test, and the corresponding test method is written.
5.1 Write Test
when writing to the database, be sure to note that the two objects written to the corresponding trainent state, otherwise there will be a state conversion error, the test code is as follows:

public void TestSave1 () {session 
  Session=null; 
  try{ 
    //Create a Session object 
    session=hibernateutils.getsession (); 
    Open session Transaction 
    session.begintransaction (); 
     
    Create a Person object and save person 
    person=new person (); 
    Person.setname ("Zhangsan"); 
    Session.save (person); 
     
    Create the Idcard object and save the 
    Idcard idcard=new idcard (); 
    Idcard.setcardno ("1111111111111"); 
    Idcard.setperson (person); 
    Session.save (Idcard); 
     
    Commit TRANSACTION, modify database 
    session.gettransaction (). commit (); 
     
  catch (Exception e) { 
    //Print error message 
    e.printstacktrace (); 
    Business rollback 
    session.gettransaction (). rollback (); 
  } finally{ 
    //Close Session 
    Hibernateutils.closesession (sessions); 
  } 
 

The data inserted is as follows:

5.2 Load Test
write the Load method, because the association relationship is bidirectional, so the corresponding load operation should be to load the other end through one end, that is, to get the corresponding person class, and through the person class to get the corresponding Idcard information, but also to set up, the code is as follows:

public void TestLoad1 () {session 
  Session=null; 
  try{ 
    //Create a Session object 
    session=hibernateutils.getsession (); 
    Open session Transaction 
    session.begintransaction (); 
     
    Gets the person object and saves the person 
    person= (person) session.load (person.class,5); 
    System.out.println ("Idcard.id:" +person.getidcard (). GetId ()); 
    System.out.println ("Idcard.cardno:" +person.getidcard (). Getcardno ()); 
     
    Create the Idcard object and save the 
    Idcard idcard= (idcard) session.load (Idcard.class, 5); 
    System.out.println ("Person.id:" +idcard.getperson (). GetId ()); 
    System.out.println ("Person.name:" +idcard.getperson (). GetName ()); 
     
    Commit TRANSACTION, modify database 
    session.gettransaction (). commit (); 
     
  catch (Exception e) { 
    //Print error message 
    e.printstacktrace (); 
    Business rollback 
    session.gettransaction (). rollback (); 
  } finally{ 
    //Close Session 
    Hibernateutils.closesession (sessions); 
  } 
 

To run the test method above, the relevant content printed on the console is as follows:

Two, two-way foreign Key Association
A two-way foreign key association can be understood as a special case of a foreign key association, especially because it is a two-way correspondence, and in the previous article it is mentioned that you can use the <many-to-one> tag if you want to add a foreign key field to a table. It will generate the corresponding foreign key columns in the relational model. You must use this label if you want to implement a two-way foreign key association.
1. Object model
first look at the object model, people and identity cards belong to a one-to-one relationship, a person corresponds to an identity, so the multiplicity between them is one-to-one, and the corresponding relationship is two-way. So its object model is the same as the bidirectional primary key one-to-one, as shown in the following figure:

2. Relationship Model
the corresponding relational model will change a lot, a one-to-one foreign key association will generate a corresponding foreign key in a table, the person and the identity card is the human relationship model will have an ID number of the primary key columns, they form a two-way one-to-one situation, the following figure:

The corresponding relationship between them is seen in the figure above, the person table has a idcard table of the primary key, forming a one-to-one foreign key association, and two-way, that is, through the person can get to Idcard, another through the idcard can also get person.
The person object and the code in the Idcard object are consistent with the object code in the previous article, not in the code list, only the configuration problem in the mapping file.
3. Mapping file
idCard.hbm.xml mapping file, Idcard table is not a mapped primary table, so you need to use the <one-to-one> tag to configure a one-to-one mapping, and you need to develop a foreign key attribute in the person relationship model, as follows:

<?xml version= "1.0"?> 
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" 
"http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd "> 
<!--generated 2014-5-18 22:27:43 by hibernate Tools 3.4.0.cr1--> 
< hibernate-mapping> 
  <class name= "Com.src.hibernate.IdCard" table= "Idcard" > 
    <id name= "id" type= " int "> 
      <generator class=" native "/> 
    </id> 
    <property name=" Cardno "type=" Java.lang.String "> 
      <column name=" Cardno "/> 
    </property> 
     
    <one-to-one name=" person "Property-ref=" Idcard "></one-to-one> 
  </class> 
 
 

Person.hbm.xml mapping file, the person table is the mapped primary table, you need to add a foreign key property column to mark the Idcard table, so you need to use the <many-to-one> tag to generate the corresponding foreign key in the person object. and also use unique to mark attributes unique.

<?xml version= "1.0"?> 
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" 
"http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd "> 
<!--generated 2014-5-18 22:27:43 by hibernate Tools 3.4.0.cr1--> 
< hibernate-mapping> 
  <class name= "Com.src.hibernate.Person" table= "person" > 
    <id name= "id" type= " int "column=" personId "> 
      <generator class=" native "/> 
    </id> 
    <property name=" name "type = "Java.lang.String" > 
      <column name= "name"/> 
    </property> 
     
    <many-to-one name= " Idcard "column=" Idcardno "unique=" true "not-null=" true "></many-to-one> 
  </class> 
</ Hibernate-mapping> 

The mapping file configuration for the object is complete, then the relational model is generated, and the SQL statement is as follows:

ALTER TABLE person drop foreign key fk8c768f55794a52ca 
drop table if exists idcard 
drop table if exists person
   
    create table Idcard (ID integer NOT NULL auto_increment, Cardno varchar (255), primary key (ID)) 
CREATE TABLE person ( PersonId integer NOT NULL auto_increment, NAME varchar (255), Idcardno integer NOT null unique, primary key (PersonId)) 
    
     alter Table Person Add index FK8C768F55794A52CA (idcardno), add constraint FK8C768F55794A52CA foreign key (Idcardno) Refe Rences Idcard (ID) 
    
   

The resulting SQL statement is the first table created, the primary key column is specified when the table is created, and the two tables are modified to specify the foreign key attributes to form a one-to-one relationship.

Write test methods, take unit tests, load two classes of objects, and get another object from one end of the object separately

Loads the object, using the Idcard object to load the person object public 
void TestLoad1 () {session 
  Session=null; 
   
  try{ 
    session=hibernateutils.getsession (); 
    Session.begintransaction (); 
     
    Gets the Idcard object that gets the person object that is uniquely associated with the object in Idcard 
    idcard idcard= (idcard) session.load (idcard.class,1); 
    System.out.println ("person.") Id= "+idcard.getperson (). GetId ()); 
    System.out.println ("Idcard.person.name=" +idcard.getperson (). GetName ()); 
     
    Gets the person object that obtains the Idcard object person 
    person= (person) session.load (person.class,1) that is uniquely associated with it in the person object; 
    System.out.println ("Idcard.id:" +person.getidcard (). GetId ()); 
    System.out.println ("Idcard.cardno:" +person.getidcard (). Getcardno ()); 
     
    Commit TRANSACTION 
    session.gettransaction (). commit (); 
  catch (Exception e) { 
    e.printstacktrace (); 
    Session.gettransaction (). rollback (); 
  } finally{ 
    Hibernateutils.closesession (session); 
  } 
 

What is generated:

Comparing two mapping relations, primary key and foreign key mapping, are bidirectional mapping relationship, you need to configure the mapping relationship at both ends of the object, the difference is that the primary key only need to use <one-to-one> because it does not need to generate property columns, However, the primary key of the table must be foreign with the primary key generation policy, and the foreign key object should be marked; The foreign key generation strategy requires the <many-to-one> tag to generate a new foreign key column.

Conclusion
one-to-one mapping in bidirectional association This has been discussed, two articles focused on two kinds of use of two-way association, in fact, is very simple, remember a sentence to generate foreign keys on the use of <many-to-one> tags, if the only then add unique attributes, <one-to-one> tag just means a one-to-one relationship. It simply indicates how one object loads another object and does not add new columns to the relational model. The next article will discuss a one-to-many association.

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.