【问题标题】:how do I add one to many relationship in hibernate?如何在休眠中添加一对多关系?
【发布时间】:2012-01-30 07:19:08
【问题描述】:

在数据库上,我有这两张表:

- Destination:
 - idDestination
 - name

- Airport:
 - idAirport
 - idDestination // FK into Destination city
 - name

地点:

  • 1 个目的地(阅读:城市)有许多机场
  • 1 个机场属于 1 个城市
  • 因此:Destination-Airports 之间的 1-Many 关系

我的 Java 类如下所示:

class Destination{
 private Integer idDestination;
 private String name;

 // getter and setters
}

class Airport{
 private Integer idAirport;
 private Destination city;
 private String name;
}

// Separate class for airports in city, since city is being used in a lot of other places
// and I'd like to keep Destination class clean
class CityAirports{
 private Destination City;
 private Set<Airport> airports;
}

休眠映射:Airport.hbm.xml

<hibernate-mapping>
    <class name="org.wah.dao.Airport" table="AIRPORT">
        <id name="idAirport" type="java.lang.Integer">
            <column name="IDAIRPORT" />
            <generator class="identity" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <many-to-one name="city" class="org.wah.dao.Destination">
            <column name="IDCITY" />
        </many-to-one>
    </class>
</hibernate-mapping>

我需要为 CityAirports 定义另一个映射到 - 检索城市内的所有机场。 - 为城市添加一个新机场。

我不确定休眠映射会是什么样子?有人可以指导我怎么做吗?

【问题讨论】:

    标签: java hibernate jakarta-ee hibernate-mapping


    【解决方案1】:

    用于目的地映射,

    <hibernate-mapping>
     <class name="org.wah.dao.Destination" table="DESTINATION">
     <id name="idDestination" type="int" column="DESTINATION_ID">
         <generator class="native" />
     </id>
     <property name="name" type="string" not-null="true" length="100" 
        column=DESTINATION_NAME" />
     <set name="destinationAirPorts" table="DESTINATION_AIRPORT" cascade="all">
      <key column="DESTINATION_ID" />
      <many-to-many column="IDAIRPORT" unique="true" class="org.wah.dao.Airport" />
     </set>
    </class>
    

    用于机场地图,

    <hibernate-mapping>
     <class name="org.wah.dao.Airport" table="AIRPORT">
     <id name="idAirport" type="int" column="IDAIRPORT">
         <generator class="native" />
     </id>
     <property name="name" type="string" not-null="true" length="100" 
        column=NAME" />
    
    </class>
    </hibernate-mapping>
    

    【讨论】:

    • 几件事.. 1.映射的根应该是CityAirports类吗? 2. 我没有名为 DESTINATION_AIRPORT 的表。你能添加一些关于这将如何工作的 cmets 吗?
    • 每个类都有一个映射文件。但是,您在这里定义了两个映射。我对这将如何工作感到有些困惑?
    • 我使用多对多元素来创建 Destination 和 Airport 实体之间的一对多关系。由于一个目的地可以有任意数量的机场,我们使用一个集合来保存这些值。在这种情况下,我们使用 Set。多对多元素通常用于创建多对多关系,这里我们将唯一性约束放在 IDAIRPORT 列上,这使得关系成为一对多。
    【解决方案2】:

    阅读提到的示例here,它巧妙地描述了您正在寻找的解决方案。 基本思想是您使用从城市到机场的多对多关系并在 IDAIRPORT 上放置唯一约束

    【讨论】:

    • CityAirports 在数据库中并没有真正的表。因此,当我们需要添加城市时,需要更新 Destination 表。将机场添加到城市时,需要更新 Airports 表。对于阅读,我们需要做类似的事情。您提到的教程有一个用于这种关系的特定表。当该类没有一个专用表时,如何进行映射?
    【解决方案3】:

    可能是这样的吗??

    <class name="org.wah.dao.CityAirports">
            <id name="caID">
                <generator class="assigned" />
            </id>
    
            <set name="Airport" cascade="save-update" >
                <key column="apID" />
                <one-to-many class="org.wah.dao.Airport" />
            </set>
            <many-to-one name="city" class="org.wah.dao.Destination">
                <column name="IDCITY" />
            </many-to-one>
    
    </class>
    

    【讨论】:

    • 你提到的 id 的 caID 是什么?
    • 没有 CityAirport 表。它引用了 db 中的 Destination 和 airport 表。
    • 嘿,您的目标表中是否有任何映射到 Airport 的内容?
    • Airport 表有一个外键 id,它引用目的地(读取:城市)表。
    【解决方案4】:

    CityAirport 类真的有必要吗?为什么不直接将Airports 列表放入您的Destination

    不确定这个 .xml 配置。但是使用注解,你会得到这样的结果:

    @Entity
    public class Destination {
       @Id
       @GeneratedValue
       private Integer idDestination;
    
       private String name;
       @OneToMany(mappedBy="destination")
       Set<Airport> airports;
        [...]
    }
    

    还有 Airport 类:

    @Entity
    public class Airport {
        @Id
        @GeneratedValue
        private Integer id;
    
        @ManyToOne
        private Destination destination;
        [...]
    }
    

    【讨论】:

    • 我在很多地方都在使用 Destination,并希望遵循封装并保持干净。感谢您的注释,但您能帮我解决一下 CityAirports 的用例吗?
    • 据我所知,您的方法无法解决。不过可能是错误的 - 您希望自动更新一个甚至没有保存在数据库中的类上的字段。从封装的角度来看,我想说 Set 方法并没有真正违反任何范例或限制。如果您担心每次加载目的地时所有机场都被加载到内存中,请不要担心 - hibernate 支持延迟加载
    • 嗯,Destination 和 Airports 作为单独的表保存在后端数据库中,甚至具有外键关系。 Java 类暗示了关系,City->Airport,其中一个城市包含多个机场。对于相反方向的遍历,即机场服务于哪个城市,我通过在 Airport 类中有一个 Destination 对象来识别它。另外,请参阅我上面发布的问题中的 airport.hbm.xml。
    猜你喜欢
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多