Directory:
1. Implementation method One: the properties corresponding to the composite primary key are put together with other normal properties of the entity
2. Implementation method Two: Extract the primary key attribute into a primary key class, the entity class simply contains a reference to the primary key class
In daily development, you encounter a situation in which a table in a database requires multiple field columns to uniquely determine a single row of records, and the table needs to use a composite primary key. In the face of this situation, Hibernate provides us with two ways to solve the compound primary key problem.
Method One: Combine the properties of the composite primary key with the other normal attributes of the entity
For example, the "id" and "name" Properties in the entity class people correspond to the composite primary key:
/* Entity class, using a composite primary key must implement the Serializable interface */
Public class people implements Serializable
{
Private static final long serialversionuid = -4888836126783955019l;
Private String ID;
private String name;
private int age;
Public people ()
{
}
Public String getId ()
{
return ID;
}
public void SetId (String ID)
{
This.id = ID;
}
Public String GetName ()
{
return name;
}
public void SetName (String name)
{
THIS.name = name;
}
public int Getage ()
{
return age;
}
public void Setage (int.)
{
This.age = age;
}
@Override
public int hashcode ()
{
final int prime = 31;
int result = 1;
result = Prime * result + ((id = = null)? 0:id.hashcode ());
result = Prime * result + ((name = = null)? 0:name.hashcode ());
return result;
}
@Override
public boolean equals (Object obj)
{
if (this = = obj)
return true;
if (obj = = null)
return false;
if (GetClass ()! = Obj.getclass ())
return false;
People other = (people) obj;
if (id = = NULL)
{
if (other.id! = null)
return false;
}
else if (!id.equals (other.id))
return false;
if (name = = NULL)
{
if (other.name! = null)
return false;
}
else if (!name.equals (other.name))
return false;
return true;
}
}
People.hbm.xml:
<?xml version= "1.0" encoding= "Utf-8"?>
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd ">
<class name= "Com.suxiaolei.hibernate.pojos.People" table= "People" >
<!--Composite PRIMARY key using Composite-id label--
<composite-id>
<!--key-property tag indicates which properties correspond to the composite primary key--
<key-property name= "id" column= "id" type= "string" ></key-property>
<key-property name= "name" column= "name" type= "string" ></key-property>
</composite-id>
<property name= "Age" column= "Age" type= "integer" ></property>
</class>
There are a few rules to note when using composite primary keys in Hibernate:
1. Entity classes that use composite primary keys must implement the Serializable interface. The reason why the serializable interface must be implemented is simple, and we look for the data in terms of the primary key. Opening the help documentation for hibernate we can find the declaration form of the Get and load method as follows:
Object load (Class theclass,serializable ID)
Object Get (Class theclass,serializable ID)
When we look for an object of a composite primary key class, we need to pass the primary key value to the ID parameter of the get () or load () method, and the ID parameter can only receive an object that implements the serializable interface. The primary key of a composite primary key class is not an attribute, so you can only create an instance of the composite primary key class (for example: New people ()), then use the Set method of the primary key property to assign the primary key value to the primary key property, and then pass the entire object to the ID parameter of the get () or load () method , the primary key value is passed, so the entity class of the composite primary key must implement the serializable interface.
2. Entity classes that use composite primary keys must override the Equals and Hashcode methods. The Equals and Hashcode methods must be rewritten and also well understood. These two methods enable you to determine whether two objects (two records) are equal. Why should you judge whether two objects are equal? Because the primary key values in any two records in the database cannot be the same, we can prevent errors in the PRIMARY KEY constraint violation by simply ensuring that the primary key values of the two objects are different in the program. Maybe here you'll wonder why entity classes that don't use composite primary keys do not override these two methods and do not have a primary key violation, because a single primary key means that the primary key value is hibernate to maintain, it will ensure that the primary key is not duplicated, and the composite primary key mode, the primary key value is the programmer's own maintenance, Therefore, you must override the Equals and Hashcode methods to determine whether the primary key for two objects is the same.
3. The overridden Equals and Hashcode methods are only related to primary key attributes, and normal properties do not affect these two methods for judgment. The reason is simple, the primary key can determine a record, and other properties cannot determine a record.
To save the test:
public class Client
{
public static void Main (string[] args)
{
Session session = Hibernateutil.getsessionfactory (). Opensession ();
Transaction tx = NULL;
Try
{
tx = Session.begintransaction ();
People people = new people ();
/* Primary key values are maintained by ourselves */
People.setid ("123456");
People.setname ("Zhangsan");
People.setage (40);
Session.save (people);
Tx.commit ();
}
catch (Exception e)
{
if (tx! = NULL)
{
Tx.rollback ();
}
E.printstacktrace ();
}
Finally
{
Session.close ();
}
}
}
Look at the database:
The data is inserted correctly into the database.
Read the data test:
public class Client
{
public static void Main (string[] args)
{
Session session = Hibernateutil.getsessionfactory (). Opensession ();
Transaction tx = NULL;
Try
{
tx = Session.begintransaction ();
/* Query the composite primary key object, you need to first build the primary key */
People peopleprimarykey = new people ();
Peopleprimarykey.setid ("123456");
Peopleprimarykey.setname ("Zhangsan");
/* Then obtain the corresponding people object in the Get method by passing the built primary key value */
People people = (people) Session.get (People.class, Peopleprimarykey);
System.out.println ("People is:" +people.getage ());
Tx.commit ();
}
catch (Exception e)
{
if (tx! = NULL)
{
Tx.rollback ();
}
E.printstacktrace ();
}
Finally
{
Session.close ();
}
}
}
Console output:
People age is:40
You can see that the data was successfully removed.
Method Two: Extract the primary key attribute into a primary key class, and the entity class simply contains a reference to the primary key class.
Primary KEY class:
/* must implement SERIALIZABLE interface */
public class Peopleprimarykey implements Serializable
{
Private static final long serialversionuid = -1190986010439330142l;
/* Composite PRIMARY KEY value */
Private String ID;
private String name;
Public Peopleprimarykey ()
{
}
/* Get and Set methods for composite PRIMARY key values */
Public String getId ()
{
return ID;
}
public void SetId (String ID)
{
This.id = ID;
}
Public String GetName ()
{
return name;
}
public void SetName (String name)
{
THIS.name = name;
}
@Override
public int hashcode ()
{
final int prime = 31;
int result = 1;
result = Prime * result + ((id = = null)? 0:id.hashcode ());
result = Prime * result + ((name = = null)? 0:name.hashcode ());
return result;
}
@Override
public boolean equals (Object obj)
{
if (this = = obj)
return true;
if (obj = = null)
return false;
if (GetClass ()! = Obj.getclass ())
return false;
Peopleprimarykey other = (peopleprimarykey) obj;
if (id = = NULL)
{
if (other.id! = null)
return false;
}
else if (!id.equals (other.id))
return false;
if (name = = NULL)
{
if (other.name! = null)
return false;
}
else if (!name.equals (other.name))
return false;
return true;
}
}
Entity class:
public class people
{
/* Hold a reference to the primary key class, using that reference as the oid*/of this class
Private Peopleprimarykey Peopleprimarykey;
private int age;
Public people ()
{
}
Public Peopleprimarykey Getpeopleprimarykey ()
{
return peopleprimarykey;
}
public void Setpeopleprimarykey (Peopleprimarykey peopleprimarykey)
{
This.peopleprimarykey = Peopleprimarykey;
}
public int Getage ()
{
return age;
}
public void Setage (int.)
{
This.age = age;
}
}
People.hbm.xml file a slight change:
<?xml version= "1.0" encoding= "Utf-8"?
<! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ Hibernate-mapping-3.0.dtd "
<class name=" Com.suxiaolei.hibernate.pojos.People "table=" People "
<!--Composite PRIMARY key using Composite-id tag-->
<!--
Name-Specifies which property the composite primary key corresponds to
Class-Specifies the type of the composite primary key property
-->
<composite-id name= "Peop Leprimarykey "class=" Com.suxiaolei.hibernate.pojos.PeoplePrimaryKey;
<!--key-property Specifies which properties are composed of the composite primary key -->
<key-property name= "id" column= "id" type= "string" ></KEY-PROPERTY>
<ke Y-property name= "name" column= "name" type= "string" ></KEY-PROPERTY>
</composite-id>
<property name= "Age" column= "Age" type= "integer" ></PROPERTY>
</class>
</ Hibernate-mapping>
Primary Key Mappings