Reputation: 3467
There are two tables: Airplane and Engine
The Engine table is made up as follows [Engine_ID, Engine_Name,Airplane_Owner_ID]
.
The Airplane table is made up as follows [Airplane_ID, Left_Engine, Right_Engine]
Left_Engine and Right_Engine are foreign keys from the Engine table, moreover Airplane_Owner_ID is the foreign key from the Airplane table. Therefore there are three one-to-one relationships defined between the Airplane and Engine tables.
I know how to specify single one-to-one relationships between two tables but how can I specify multiple relationships between two tables? Is it the same process?
How can these relationships be specified in Hibernate?
Upvotes: 0
Views: 504
Reputation: 3467
As @APC said, Cyclic dependencies between Engine and Airplane is a bad design. But with the solution described below, Engine.Airplane_Owner_ID could be implemented only as logical back-link which not exist in Database table.
Airplane.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping">
<hibernate-mapping>
<class name="Airplane" table="AIRPLANE">
<id name="id" type="int" column="AIRPLANE_ID">
<generator class="native"/>
</id>
<property name="name" column="AIRPLANE_NAME" type="string" length="250"/>
<many-to-one name="rightEngine" class="Engine" cascade="save-update" unique="true"/>
<many-to-one name="leftEngine" class="Engine" cascade="save-update" unique="true"/>
</class>
</hibernate-mapping>
Engine.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping">
<hibernate-mapping>
<class name="Engine" table="ENGINE">
<id name="id" type="int" column="ENGINE_ID">
<generator class="native"/>
</id>
<property name="name" column="ENGINE_NAME" type="string" length="250"/>
<property name="position" column="ENGINE_POSITION" type="java.lang.Byte" />
<one-to-one name="ownerAirplane" property-ref="rightEngine" />
</class>
</hibernate-mapping>
Airplane.java
public class Airplane {
private int id;
private String name;
private Engine rightEngine;
private Engine leftEngine;
public Airplane(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Engine getRightEngine() {
return rightEngine;
}
public void setRightEngine(Engine rightEngine) {
this.rightEngine = rightEngine;
}
public Engine getLeftEngine() {
return leftEngine;
}
public void setLeftEngine(Engine leftEngine) {
this.leftEngine = leftEngine;
}
@Override
public String toString() {
return "Airplane{" +
"id=" + id +
", name='" + name + '\'' +
", rightEngline=" + (rightEngine == null ? null : rightEngine.getName()) +
", leftEngine=" + (leftEngine == null ? null : leftEngine.getName()) +
'}';
}
}
Engine.java
public class Engine {
private int id;
private String name;
private byte position;//0=left, 1=right
private Airplane ownerAirplane;
/**
* @param name
* @param position 0=left, 1=right
*/
public Engine(String name, byte position) {
this.name = name;
this.position = position;
}
public Airplane getOwnerAirplane() {
return ownerAirplane;
}
public void setOwnerAirplane(Airplane ownerAirplane) {
this.ownerAirplane = ownerAirplane;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* @return 0=left, 1=right
*/
public byte getPosition() {
return position;
}
/**
* @param position 0=left, 1=right
*/
public void setPosition(byte position) {
this.position = position;
}
@Override
public String toString() {
return "Engine{" +
"id=" + id +
", name='" + name + '\'' +
", position=" + position +
", ownerAirplane=" + (ownerAirplane == null ? null : ownerAirplane.getName()) +
'}';
}
}
Main.java
public static void main(final String[] args) throws Exception {
Session session = ourSessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
Engine engineRight1 = new Engine("engineRight1", (byte) 1);
Engine engineLeft1 = new Engine("engineLeft1", (byte) 0);
Airplane airplane1 = new Airplane("Airplane1");
Engine engineRight2 = new Engine("engineRight2", (byte) 1);
Engine engineLeft2 = new Engine("engineLeft2", (byte) 0);
Airplane airplane2 = new Airplane("Airplane2");
Engine engineRight3 = new Engine("engineRight3", (byte) 1);
Engine engineLeft3 = new Engine("engineLeft3", (byte) 0);
Airplane airplane3 = new Airplane("Airplane3");
engineLeft1.setOwnerAirplane(airplane1);
engineRight1.setOwnerAirplane(airplane1);
airplane1.setLeftEngine(engineLeft1);
airplane1.setRightEngine(engineRight1);
engineRight2.setOwnerAirplane(airplane2);
airplane2.setRightEngine(engineRight2);
// airplane2.setLeftEngine(engineLeft1);
engineRight3.setOwnerAirplane(airplane3);
airplane3.setLeftEngine(engineLeft3);
session.save(airplane1);
session.save(airplane2);
session.save(airplane3);
session.save(engineLeft1);
session.save(engineLeft2);
session.save(engineLeft3);
session.save(engineRight1);
session.save(engineRight2);
session.save(engineRight3);
transaction.commit();
} catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
}
Upvotes: 0
Reputation: 146349
"Left_Engine and Right_Engine are foreign keys from the Engine table,
moreover Airplane_Owner_ID is the foreign key from the Airplane table."
Your problem is Airplane
is referenced by Engine
and Engine
is referenced by Airplane
. In your data model each table is the child of the other. Cyclic dependencies are just as bad in the database as they are in other parts of the stack.
The best solution is to fix the data model.
Left_Engine
and Right_Engine
from Airplane
Engine_Position
to Engine
Engine (Airplane_Owner_ID, Engine_Position)
Engine_Position
for LEFT, RIGHT, or use a foreign key on a reference data tableThis model has two virtues:
Upvotes: 2