2017-08-06 69 views
0

表之间的关系有两个表:飞机和发动机指定多个一到一个Hibernate中

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

Left_Engine和Right_Engine从发动机表的外键,而且Airplane_Owner_ID是从飞机表的外键。因此在飞机和发动机表格之间定义了三种一对一的关系。

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

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

回答

0

正如@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(); 
     } 
2

“Left_Engine和Right_Engine从发动机表的外键,
而且Airplane_Owner_ID是从飞机表的外键。”

您的问题是AirplaneEngineEngine引用由Airplane引用。在你的数据模型中,每个表格都是另一个表格的孩子。循环依赖在数据库中与在栈中的其他部分一样糟糕。

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

  • Left_EngineRight_EngineAirplane
  • 添加Engine_PositionEngine
  • Engine (Airplane_Owner_ID, Engine_Position)
  • 添加唯一约束也Engine_Position左增加一个检查约束,RIGHT,或使用一个外键参考数据表

该模型有两个优点:

  1. 清除所有权 - 飞机拥有引擎,引擎不拥有飞机。
  2. 它很容易支持具有发动机的不同配置平面(一,三,四......)
+2

确保你从飞机下降Left_Engine和Right_Engine前安全着陆。 –

+0

我对数据库表中的这个问题不负责任。而且,我没有权限更正它。这个数据库是给我的,我必须为它开发一个数据访问层。 – Razavi

+1

@razavi--不幸的是,这个世界似乎充满了对付那些没有能力改变它们的数据模型的人。关键是,数据模型被破坏了,你为它编写的代码也将被破坏。我的建议是现在提出这个问题。那么至少在其他人抱怨你的数据访问代码无法正常工作时,你会被覆盖。 – APC

相关问题