[英]Bidirectional one-to-one relationships in Hibernate
There are two tables: Airplane and Engine 有两个表:飞机和引擎
The Engine table is made up as follows [Engine_ID, Engine_Name,Airplane_Owner_ID]
. 引擎表由以下[Engine_ID, Engine_Name,Airplane_Owner_ID]
。
The Airplane table is made up as follows [Airplane_ID, Left_Engine, Right_Engine]
“飞机”表的组成如下[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. Left_Engine和Right_Engine是引擎表中的外键,此外Airplane_Owner_ID是飞机表中的外键。 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? 在Hibernate中如何指定这些关系?
"Left_Engine and Right_Engine are foreign keys from the Engine table, “ Left_Engine和Right_Engine是引擎表中的外键,
moreover Airplane_Owner_ID is the foreign key from the Airplane table." 而且Airplane_Owner_ID是Airplane表中的外键。”
Your problem is Airplane
is referenced by Engine
and Engine
is referenced by Airplane
. 您的问题是Engine
引用了Airplane
而Airplane
引用了Engine
。 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
从Airplane
放下Left_Engine
和Right_Engine
Engine_Position
to Engine
将Engine_Position
添加到Engine
Engine (Airplane_Owner_ID, Engine_Position)
在Engine (Airplane_Owner_ID, Engine_Position)
上添加唯一约束Engine (Airplane_Owner_ID, Engine_Position)
Engine_Position
for LEFT, RIGHT, or use a foreign key on a reference data table 还在Engine_Position
为LEFT,RIGHT添加检查约束,或在参考数据表上使用外键 This model has two virtues: 该模型具有两个优点:
As @APC said, Cyclic dependencies between Engine and Airplane is a bad design. 正如@APC所说,引擎与飞机之间的循环依赖关系是一个糟糕的设计。 But with the solution described below, Engine.Airplane_Owner_ID could be implemented only as logical back-link which not exist in Database table. 但是使用下面描述的解决方案,Engine.Airplane_Owner_ID只能实现为数据库表中不存在的逻辑反向链接。
Airplane.hbm.xml 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 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 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 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 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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.