Hibernate中的双向一对一关系

时间:2017-08-06 05:34:10

标签: java hibernate mapping one-to-one

有两个表:飞机和引擎

引擎表格如下[Engine_ID, Engine_Name,Airplane_Owner_ID] 飞机表格如下[Airplane_ID, Left_Engine, Right_Engine]

组成

Left_Engine和Right_Engine是Engine表中的外键,而且Airplane_Owner_ID是Airplane表中的外键。因此,在飞机和引擎表之间定义了三种一对一的关系。

我知道如何在两个表之间指定单个一对一关系但是如何指定两个表之间的多个关系?是同一个过程吗?

如何在Hibernate中指定这些关系?

2 个答案:

答案 0 :(得分:2)

  

" Left_Engine和Right_Engine是Engine表中的外键,
  此外,Airplane_Owner_ID是Airplane表中的外键。"

Airplane引用了您的问题EngineEngine引用了Airplane。在您的数据模型中,每个表都是另一个表的子表。循环依赖在数据库中和在堆栈的其他部分一样糟糕。

最佳解决方案是修复数据模型。

  • Left_Engine
  • 中删除Right_EngineAirplane
  • Engine_Position添加到Engine
  • Engine (Airplane_Owner_ID, Engine_Position)
  • 上添加唯一约束
  • 还在Engine_Position上为LEFT,RIGHT添加检查约束,或在参考数据表上使用外键

这个模型有两个优点:

  1. 明确所有权 - 飞机拥有发动机,发动机不拥有飞机。
  2. 它可以轻松支持具有不同发动机配置的飞机(一,三,四......)

答案 1 :(得分:0)

正如@APC所说,引擎和飞机之间的循环依赖关系是一个糟糕的设计。但是使用下面描述的解决方案,Engine.Airplane_Owner_ID只能实现为Database表中不存在的逻辑反向链接。

Airplane.hbm.xml

DateTimeKind.Unspecified

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="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>

Airplane.java

<?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>

Engine.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()) +
                '}';
    }
}

Main.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()) +
                '}';
    }
}