In Hibernate there are various ways of defining identifiers for table mapping. However, the following two are the most commonly and widely used strategies based on the underlying database.
| identity |
|
| sequence |
|
| identity |
|
| sequence |
|
Association Diagram
__________
|Person |
----------
|
____|_____
|Address |
----------
However, we will store both the above entities in a single table. And the database structure is as follows,
----------------
|Person |
|----------------|
|id:long |
|name:String |
|address:Address |
----------------
----------------
|Address |
|----------------|
|line1:String |
|line2:String |
|city:String |
|state:String |
|zipCode:String |
----------------
CREATE TABLE PERSON (
person_id INTEGER NOT NULL,
name VARCHAR(50),
line1 VARCHAR(50),
line2 VARCHAR(50),
city VARCHAR(25),
state VARCHAR(25),
zip-code VARCHAR(25),
);
Lets look at the Hibernate mapping that involves in mapping both the entities into a single table. <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.fazlan.Person" table="PERSON">
<id name="id" column="person_id">
<generator class="increment" />
</id>
<property name="name"/>
<component name="address" class="org.fazlan.Address">
<proeprty name="line1" />
<proeprty name="line2" />
<proeprty name="city" />
<proeprty name="state" />
<proeprty name="zipCode" column="zip-code"/>
</component>
</class>
</hibernate-mapping>
Association Diagram
__________
| Club |
-----------------
|*
|
____|*____
| Player |
----------------
Class Diagram
___________
|Player |
-------------------
|id:long |
|name:String |
|clubs:Set |
-------------------
__________________
|Club |
------------------------------
|id:long |
|name:String |
|contractedPlayers:Set |
------------------------------
Following is the database structure,CREATE TABLE CLUB (
club_id INTEGER NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
CREATE TABLE PLAYER (
player_id INTEGER NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
CREATE TABLE CONTRACT (
club_id,
player_id,
PRIMARY KEY (club_id, player_id),
FOREIGN KEY (club_id) REFERENCES CLUB(club_id),
FOREIGN KEY (player_id) REFERENCES PLAYER(player_id),
);
Following is the hibernate mapping involved,<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.fazlan.beans.Club">
<id name="id" column="club_id">
<generator class="increment" />
</id>
<property name="name" />
<set name="contractedPlayers" table="contract" inverse="true">
<key column="club_id" />
<many-to-many class="Player" column="player_id"/>
</set>
</class>
<class name="org.fazlan.beans.Player">
<id name="id" column="player_id">
<generator class="increment" />
</id>
<property name="name" />
<set name="clubs" table="contract">
<key column="player_id" />
<many-to-many class="Club" column="club_id" />
</set>
</class>
</hibernate-mapping>
However, with this approach, we cannot model data specific to the association with the contract(e.i: start-date and end-date of the contract). The next approach will look at how we can model such many-to-many associations.Association Diagram _______________ | Club | ----------------- | ______|*_______ | Contract | ----------------- |* ______|________ | Player | ----------------- Class Diagram _______________ |Player | ----------------- |id:long | |name:String | ----------------- _______________ |Club | ----------------- |id:long | |name:String | ----------------- ______________________________ |Contract | -------------------------------- |contract_id:long | |club:Club | |player:Player | |startDate:Date | |endDate:Date | --------------------------------Here, the association between a Player and a Club will be represented using an association entity, namely Contract. Following is the database structure,
CREATE TABLE CLUB (
club_id INTEGER NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
CREATE TABLE PLAYER (
player_id INTEGER NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
CREATE TABLE CONTRACT (
contract_id INTEGER NOT NULL,
club_id,
player_id,
start_date Date,
end_date Date,
PRIMARY KEY (contract_id),
FOREIGN KEY (club_id) REFERENCES CLUB(club_id),
FOREIGN KEY (player_id) REFERENCES PLAYER(player_id),
);
Following is the Hibernate mapping involved,<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.fazlan.beans.Club">
<id name="id" column="club_id">
<generator class="increment" />
</id>
<property name="name" />
</class>
<class name="org.fazlan.beans.Player">
<id name="id" column="club_id">
<generator class="increment" />
</id>
<property name="name" />
</class>
<class name="org.fazlan.beans.Contract">
<id name="id" column="contract_id">
<generator class="increment" />
</id>
<property name="startDate" column="start_date"/>
<property name="endDate" column="end_date"/>
<many-to-one name="club" column="club_id" not-null="true" />
<many-to-one name="player" column="player_id" not-null="true" />
</class>
</hibernate-mapping>
Alternatively, you can model the many-to-many relationship using an composite-element. The next section looks at this.Association Diagram
_______________
| Club |
-----------------
|
______|*_______
| Contract |
-----------------
|*
______|________
| Player |
-----------------
Class Diagram
_______________
|Player |
-----------------
|id:long |
|name:String |
-----------------
_______________
|Club |
-----------------
|id:long |
|name:String |
|contracts:List |
-----------------
______________________________
|Contract |
--------------------------------
|id:long |
|player:Player |
|startDate:Date |
|endDate:Date |
--------------------------------
Following is the database structure,CREATE TABLE CLUB (
club_id INTEGER NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
CREATE TABLE PLAYER (
player_id INTEGER NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
);
CREATE TABLE CONTRACT (
contract_id INTEGER NOT NULL,
club_id,
player_id,
start_date Date,
end_date Date,
PRIMARY KEY (contract_id),
FOREIGN KEY (club_id) REFERENCES CLUB(club_id),
FOREIGN KEY (player_id) REFERENCES PLAYER(player_id),
);
Following is the Hibernate mapping involved,<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="org.fazlan.beans.Club">
<id name="id" column="club_id">
<generator class="increment" />
</id>
<property name="name" />
<list name="contracts" table="contract">
<key column="club_id" />
<index-column column="contract_id" />
<composite-element class="org.fazlan.beans.Contract">
<property name="startDate" column="start_date"/>
<property name="endDate" column="end_date"/>
<many-to-one name="player" column="player_id">
</composite-element>
</list>
</class>
<class name="org.fazlan.beans.Player">
<id name="id" column="player_id">
<generator class="increment" />
</id>
<property name="name" />
</class>
</hibernate-mapping>
Summary:
CREATE TABLE Parent(
parent_id INTEGER NOT NULL,
PRIMARY KEY (parent_id)
);
CREATE TABLE Child(
child_id INTEGER NOT NULL,
parent_id INTEGER NOT NULL,
PRIMARY KEY (child_id),
FOREIGN KEY (parent_id) REFERENCES Parent
);
package org.fazlan;
public class Parent {
private long id;
private Set children = new HashSet();
// getters and setters
}
package org.fazlan;
public class Child {
private long id;
private Parent parent;
// getters and setters
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.fazlan">
<class name="Parent" table="parent">
. . .
<set name="children" inverse="true">
<key column="parent_id" />
<one-to-many class"Child" />
</set>
</class>
<class name="Child" table="child">
. . .
<many-to-one name="parent" column="parent_id" not-null="true"/>
</class>
</hibernate-mapping>
Parent p1 = new Parent(); session.save(p1); session.flush();
Hibernate: select max(parent_id) from hibernatedb.Parent
Hibernate: insert into hibernatedb.Parent (parent_id) values (?)
Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
c.setParent(p);
p.getChildren().add(c);
session.save(c);
session.flush();
Alternatively, you can add the following method to parent.
public void addChild(Child c) {
c.setParent(this);
getChildren().add(c);
}
Updated code will look like this,Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.save(c);
session.flush();
<set name="children" inverse="false" >
<key column="parent_id" />
<one-to-many class"Child" />
</set>
Hibernate: insert into hibernatedb.Child (parent_id, child_id) values (?, ?)
Hibernate: update hibernatedb.Child set parent_id=? where child_id=?
<set name="children" inverse="true" >
<key column="parent_id" />
<one-to-many class"Child" />
</set>
Hibernate: insert into hibernatedb.Child (parent_id, child_id) values (?, ?)
<set name="children" inverse="true" cascase="all">
<key column="parent_id" />
<one-to-many class"Child" />
</set>
Simplified code,Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.flush();
Parent p = (Parent) session.load(Parent.class, pid);
session.delete(p);
session.flush();
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c); // remove link
c.setParent(null); // NOT NULL constraint violation
session.flush();
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
session.delete(c);
session.flush();
<set name="children" inverse="true" cascade="all-delete-orphan">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
Parent p1 = (Parent) session.get(Parent.class,1l);
Child c1 = p1.getChildren().iterator().next();
p1.getChildren().remove(c1);
session.flush();
Summary:
1: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2: xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3: <modelVersion>4.0.0</modelVersion> 4: <groupId>org.fazlan</groupId> 5: <artifactId>org.fazlan.employee.service.stub</artifactId> 6: <packaging>jar</packaging> 7: <version>1.0-SNAPSHOT</version> 8: <name>org.fazlan.employee.service.stub</name> 9: <url>http://maven.apache.org</url> 10: <dependencies> 11: <dependency> 12: <groupId>org.apache.axis2</groupId> 13: <artifactId>axis2</artifactId> 14: <version>${axis2.version}</version> 15: </dependency> 16: <dependency> 17: <groupId>wsdl4j</groupId> 18: <artifactId>wsdl4j</artifactId> 19: <version>${wsdl4j.version}</version> 20: </dependency> 21: <dependency> 22: <groupId>org.apache.ws.commons.axiom</groupId> 23: <artifactId>axiom-api</artifactId> 24: <version>${axiom.api.version}</version> 25: </dependency> 26: <dependency> 27: <groupId>commons-logging</groupId> 28: <artifactId>commons-logging</artifactId> 29: <version>${commons-logging.version}</version> 30: </dependency> 31: <dependency> 32: <groupId>org.apache.neethi</groupId> 33: <artifactId>neethi</artifactId> 34: <version>${neethi.version}</version> 35: </dependency> 36: <dependency> 37: <groupId>org.apache.ws.commons.schema</groupId> 38: <artifactId>XmlSchema</artifactId> 39: <version>${XmlSchema.version}</version> 40: </dependency> 41: <dependency> 42: <groupId>org.apache.ws.commons.axiom</groupId> 43: <artifactId>axiom-impl</artifactId> 44: <version>${axiom-impl.version}</version> 45: </dependency> 46: <dependency> 47: <groupId>org.apache.axis2</groupId> 48: <artifactId>axis2-transport-local</artifactId> 49: <version>${axis2.version}</version> 50: </dependency> 51: <dependency> 52: <groupId>org.apache.axis2</groupId> 53: <artifactId>axis2-transport-http</artifactId> 54: <version>${axis2.version}</version> 55: </dependency> 56: </dependencies> 57: <build> 58: <plugins> 59: <plugin> 60: <groupId>org.apache.maven.plugins</groupId> 61: <artifactId>maven-antrun-plugin</artifactId> 62: <version>1.1</version> 63: <executions> 64: <execution> 65: <id>source-code-generation</id> 66: <phase>process-resources</phase> 67: <goals> 68: <goal>run</goal> 69: </goals> 70: <configuration> 71: <tasks> 72: <java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true"> 73: <arg line="-uri src/main/resources/EmployeeService.wsdl -u -uw -o target/generated-code 74: -p org.fazlan.employee.service.stub 75: -ns2p http://service.employee.fazlan.org=org.fazlan.employee.service.stub,http://beans.service.employee.fazlan.org/xsd=org.fazlan.employee.service.stub.beans.xsd,http://exceptions.service.employee.fazlan.org/xsd=org.fazlan.employee.service.stub.exceptions.xsd"/> 76: <classpath refid="maven.dependency.classpath"/> 77: <classpath refid="maven.compile.classpath"/> 78: <classpath refid="maven.runtime.classpath"/> 79: </java> 80: </tasks> 81: </configuration> 82: </execution> 83: </executions> 84: </plugin> 85: <plugin> 86: <groupId>org.codehaus.mojo</groupId> 87: <artifactId>build-helper-maven-plugin</artifactId> 88: <executions> 89: <execution> 90: <id>add-source</id> 91: <phase>generate-sources</phase> 92: <goals> 93: <goal>add-source</goal> 94: </goals> 95: <configuration> 96: <sources> 97: <source> 98: target/generated-code/src 99: </source> 100: </sources> 101: </configuration> 102: </execution> 103: </executions> 104: </plugin> 105: </plugins> 106: </build> 107: <properties> 108: <axis2.version>1.6.1</axis2.version> 109: <wsdl4j.version>1.6.2</wsdl4j.version> 110: <commons-logging.version>1.1.1</commons-logging.version> 111: <neethi.version>2.0.4</neethi.version> 112: <axiom.api.version>1.2.12</axiom.api.version> 113: <axiom-impl.version>1.2.12</axiom-impl.version> 114: <XmlSchema.version>1.4.7</XmlSchema.version> 115: </properties> 116: </project>
1: import org.apache.axis2.AxisFault; 2: import org.fazlan.employee.service.stub.beans.xsd.Employee; 3: public class Main { 4: public static void main(String... args) throws Exception { 5: EmployeeServiceStub service = new EmployeeServiceStub(); 6: Employee e = new Employee(); 7: e.setId(1); 8: e.setFirstName("Fazlan"); 9: e.setLastName("Sabar"); 10: int id = service.addEmployee(e); 11: System.out.println(id); 12: Employee[] employees = service.getAllEmployees(); 13: for(Employee em : employees) { 14: System.out.println(em.getId()); 15: System.out.println(em.getFirstName()); 16: System.out.println(em.getLastName()); 17: System.out.println("---------------"); 18: } 19: } 20: } 
org.fazlan.employee.service
`-- src
|-- main
| `-- java
| `-- org
| `-- fazlan
| `-- employee
| `-- service
|
`-- test
`-- java
`-- org
`-- fazlan
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.fazlan</groupId>
<artifactId>org.fazlan.employee.service</artifactId>
<packaging>aar</packaging>
<version>1.0-SNAPSHOT</version>
<name>org.fazlan.employee.service</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-aar-maven-plugin</artifactId>
<version>1.6.1</version>
<!--<version>${orbit.version.axis2}</version>-->
<extensions>true</extensions>
<configuration>
<aarName>org.fazlan.employee.service</aarName>
</configuration>
</plugin>
</plugins>
</build>
</project>
POJO to model employee,
//org.fazlan.employee.service.beans.Employee.java
public class Employee {
private int id;
private String firstName;
private String lastName;
// getter and setter methods
}
POJO to model the employee exception,
//org.fazlan.employee.service.exceptions.EmployeeException.java
public class EmployeeException extends java.lang.Exception {
}
The service class with the logic to manage employees,
//org.fazlan.employee.service.EmployeeService.java
public class EmployeeService {
private static final Map employeeMap = new HashMap();
private static int index = 0;
public int addEmployee(Employee employee) throws EmployeeException {
employee.setId(++index);
employeeMap.put(index, employee);
return index;
}
public Employee getEmployee(int employeeId) throws EmployeeException {
return employeeMap.get(employeeId);
}
public Employee[] getAllEmployees() throws EmployeeException{
return employeeMap.values().toArray(new Employee[employeeMap.size()]);
}
}
<service name="EmployeeService" scope="application">
<messageReceivers>
<!--messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/-->
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<parameter name="ServiceClass">
org.fazlan.employee.service.EmployeeService
</parameter>
</service>
org.fazlan.employee.service
`-- src
|-- main
| |-- java
| | `-- org
| | `-- fazlan
| | `-- employee
| | `-- service
| | |-- beans
| | |-- exceptions
| | `-- util
| `-- resources
| `-- META-INF
`-- test
`-- java
`-- org
`-- fazlan