指定多个一到一个Hibernate中
问题描述:
表之间的关系有两个表:飞机和发动机指定多个一到一个Hibernate中
引擎表由如下[Engine_ID, Engine_Name,Airplane_Owner_ID]
。
飞机表由如下[Airplane_ID, Left_Engine, Right_Engine]
Left_Engine和Right_Engine从发动机表的外键,而且Airplane_Owner_ID是从飞机表的外键。因此在飞机和发动机表格之间定义了三种一对一的关系。
我知道如何指定两个表之间的单一一对一关系,但是如何指定两个表之间的多个关系?这是同一个过程吗?
这些关系如何在Hibernate中指定?
答
正如@APC说,发动机和飞机之间的循环依赖是一个不好的设计。但是通过下面描述的解决方案,Engine.Airplane_Owner_ID只能作为数据库表中不存在的逻辑反向链路实现。
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>
飞机。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();
}
答
“Left_Engine和Right_Engine从发动机表的外键,
而且Airplane_Owner_ID是从飞机表的外键。”
您的问题是Airplane
由Engine
和Engine
引用由Airplane
引用。在你的数据模型中,每个表格都是另一个表格的孩子。循环依赖在数据库中与在栈中的其他部分一样糟糕。
最好的解决方案是修复数据模型。
- 降
Left_Engine
和Right_Engine
从Airplane
- 添加
Engine_Position
到Engine
- 上
Engine (Airplane_Owner_ID, Engine_Position)
- 添加唯一约束也
Engine_Position
左增加一个检查约束,RIGHT,或使用一个外键参考数据表
该模型有两个优点:
- 清除所有权 - 飞机拥有引擎,引擎不拥有飞机。
- 它很容易支持具有发动机的不同配置平面(一,三,四......)
确保你从飞机下降Left_Engine和Right_Engine前安全着陆。 –
我对数据库表中的这个问题不负责任。而且,我没有权限更正它。这个数据库是给我的,我必须为它开发一个数据访问层。 – Razavi
@razavi--不幸的是,这个世界似乎充满了对付那些没有能力改变它们的数据模型的人。关键是,数据模型被破坏了,你为它编写的代码也将被破坏。我的建议是现在提出这个问题。那么至少在其他人抱怨你的数据访问代码无法正常工作时,你会被覆盖。 – APC