Hibernate - 如何将新类映射到两个现有表

发布于 2024-09-17 17:42:08 字数 422 浏览 3 评论 0原文

我有两个实体:车辆和武器类。它们分别映射到Vehicle.hbm.xml和Weapon.hbm.xml。两者都有各自的 DAO。一切都工作正常。

这是我的想法。我想创建一个类 VehicleWeapon ,它具有车辆和武器实体的所有属性。我想声明一个 Hibernate 映射文件:VehicleWeapon.hbm.xml。我希望映射文件中的属性与武器和车辆实体的属性相匹配。

这样,当我添加、删除或保存 VehicleWeapon 实体时,相应的更改将反映在支持的 Vehicle 和 Weapon 表上。 (我可能可以进行 HQL 查询,但我想首先知道我所问的想法是否可行)。

这可能吗?如果是的话,你能给我举个例子吗? (当然,车辆和武器类是假设的类。我确实有一个实际场景,我需要实现这个想法)。

或者还有什么更好的选择?您能提供直接链接或具体示例吗?多谢。

I have two entities: Vehicle and Weapon classes. They are mapped respectively to Vehicle.hbm.xml and Weapon.hbm.xml. Both have their respective DAOs. All are working fine.

Here's my idea. I want to create a class VehicleWeapon that has all the properties of the Vehicle and Weapon entities. I want to declare a Hibernate mapping file: VehicleWeapon.hbm.xml. I want the properties in the mapping file to match the properties of the Weapon and Vehicle entities.

So that when I add, delete, or save a VehicleWeapon entity, the corresponding changes will reflect on the backing Vehicle and Weapon tables. (I could probably do an HQL query, but I want to know first if the idea I'm asking is doable).

Is this possible? If yes, can you show me an example? (Of course, the Vehicle and Weapon classes are hypothetical classes. I do have an actual scenario where I need this idea to be implemented).

Or what better options are there? Can you provide a direct link or concrete example? Thanks a lot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

仙气飘飘 2024-09-24 17:42:08

我找到了一个可行的解决方案。正如我之前提到的,我不允许修改车辆和武器实体以及相应的映射文件。甚至连一个注释都不允许。

我通过谷歌搜索本的建议找到了这个答案,这让我找到了这些文章:
http://www.mkyong.com/hibernate/hibernate -一对一关系示例/
http://www.vaannila .com/hibernate/hibernate-example/hibernate-mapping-one-to-one-1.html

mkyong 的建议很好,但我不喜欢像我一样保留和分配主键的想法无法编辑车辆和武器类的映射文件。请参阅评论“一对一关系的主要困难是确保为两者分配相同的主键”

vaannila 的建议在某种程度上很有趣。它建立一对一的关系,但不需要对其他映射文件进行任何编辑。

首先,我声明了我的 VehicleWeapon.hbm.xml,如下所示:

<hibernate-mapping package="com.armory">

    <id name="id" type="long" >
        <column name="id"  />
        <generator class="native" />
    </id>

    <many-to-one name="vehicle" class="Vehicle" 
            column="vehicle_column"  cascade="all" unique="true" />

    <many-to-one name="weapon" class="Weapon" 
            column="weapon_column"  cascade="all" unique="true" />

然后我声明了我的标准 VehicleWeapon POJO 类。以及相应的DAO实现。

我运行了几个 Junit/Spring 测试。我能够毫无问题地保存、删除、检索。所有操作都会级联到相应的武器和车辆表。

此方法的唯一缺点是 Hibernate 将创建第三个表vehicle_weapon,其中分别包含车辆和武器表的 id 作为参考。

好处是我没有编辑任何现有实体或映射文件。我创建了一个新对象,并从两个表组成了一个新对象。

我仍然希望能够直接映射到武器和车辆的属性,而不是直接映射到武器和车辆实体。但就目前而言,我认为这是可以接受的。

I found a working solution. As I mentioned earlier, I'm not allowed to modify the Vehicle and Weapon entities and the corresponding mapping files. Not even a single annotation is allowed.

I found this answer by Googling Ben's suggestion above which lead me to these articles:
http://www.mkyong.com/hibernate/hibernate-one-to-one-relationship-example/
and http://www.vaannila.com/hibernate/hibernate-example/hibernate-mapping-one-to-one-1.html

The suggestion from mkyong is good but I didn't like the idea of keeping and assigning primary keys both ways as I have no way of editing the mapping files from the Vehicle and Weapon classes. See the comment "the main difficulty with one-to-one relationship is ensuring both are assigned the same primary key"

The suggestion from vaannila is somehow intriguing. It does a one-to-one relationship but without requiring any edits on other mapping files.

First, I declared my VehicleWeapon.hbm.xml as follows:

<hibernate-mapping package="com.armory">

    <id name="id" type="long" >
        <column name="id"  />
        <generator class="native" />
    </id>

    <many-to-one name="vehicle" class="Vehicle" 
            column="vehicle_column"  cascade="all" unique="true" />

    <many-to-one name="weapon" class="Weapon" 
            column="weapon_column"  cascade="all" unique="true" />

Then I declared my standard VehicleWeapon POJO class. And the corresponding DAO implementation.

I run a couple of Junit/Spring tests. I was able to save, delete, retrieve without problems. All actions cascade to the corresponding Weapon and Vehicle tables.

The only downside with this method is Hibernate will create a third table vehicle_weapon that contains the id for the vehicle and weapon tables respectively as a reference.

The good thing is I didn't edit any existing entities or mapping files. I created a new one and compose a new object from two tables.

I still like to be able to map directly to the Weapon and Vehicle's properties instead of mapping directly to the Weapon and Vehicle entities. But for now, I think this is acceptable.

戏剧牡丹亭 2024-09-24 17:42:08

Hibernate 支持使用 元素(或使用注释时的 @SecondaryTable 注释)跨多个表持久保存一个实体类。从文档中:

5.1.20 。加入

使用元素,它是
可以映射一个的属性
类到几个具有
一对一的关系。例如:

<前><代码><加入
表=“表名”(1)
架构=“所有者”(2)
目录=“目录”(3)
fetch="加入|选择" (4)
逆=“真|假”(5)
可选=“真|假”> (6)

<键.../>>

<属性.../>>
...

  1. table:连接表的名称。
  2. schema(可选):覆盖根指定的架构名称
    元素。
  3. catalog(可选):覆盖根指定的目录名称
    元素。
  4. fetch(可选 - 默认为 join):如果设置为 join,则为默认值,
    Hibernate 将使用内连接来
    检索由类定义的
    或其超类。它将使用一个
    由 a 定义的 a 的外连接
    子类。如果设置为选择则
    Hibernate 将使用顺序选择
    对于在子类上定义的
    仅当一行时才会发出此消息
    代表一个实例
    子类。内连接仍将是
    用于检索由以下定义的
    该类及其超类。
  5. inverse(可选 - 默认为 false):如果启用,Hibernate 将不会
    插入或更新属性
    由此连接定义。
  6. 可选(可选 - 默认为false):如果启用,Hibernate 将
    仅当属性满足时才插入行
    此连接定义的值都是非空的。它
    将始终使用外连接
    检索属性。

例如,地址信息
人可以被映射到一个单独的
表同时保留值类型
所有属性的语义:

<类名=“人”
    表=“人员”>

    ...

    <连接表=“地址”>
        <关键列=“ADDRESS_ID”/>
        <属性名称=“地址”/>
        <属性名称=“zip”/>
        <属性名称=“国家/地区”/>
    
    ...

此功能通常仅适用于
遗留数据模型。我们建议少一些
表比类和细粒度
域模型。不过,它很有用
用于在继承之间切换
单一的映射策略
层次结构,稍后解释。

像您一样使用组合是另一种选择,但它显然会引入另一个表(用于“聚合”实体)。

Hibernate provides support to persist one entity class across multiple tables using the <join> element (or the @SecondaryTable annotation when using annotations). From the documentation:

5.1.20. Join

Using the <join> element, it is
possible to map properties of one
class to several tables that have a
one-to-one relationship. For example:

<join
        table="tablename"                        (1)
        schema="owner"                           (2)
        catalog="catalog"                        (3)
        fetch="join|select"                      (4)
        inverse="true|false"                     (5)
        optional="true|false">                   (6)

        <key ... />

        <property ... />
        ...
</join>
  1. table: the name of the joined table.
  2. schema (optional): overrides the schema name specified by the root
    element.
  3. catalog (optional): overrides the catalog name specified by the root
    <hibernate-mapping> element.
  4. fetch (optional - defaults to join): if set to join, the default,
    Hibernate will use an inner join to
    retrieve a <join> defined by a class
    or its superclasses. It will use an
    outer join for a defined by a
    subclass. If set to select then
    Hibernate will use a sequential select
    for a <join> defined on a subclass.
    This will be issued only if a row
    represents an instance of the
    subclass. Inner joins will still be
    used to retrieve a <join> defined by
    the class and its superclasses.
  5. inverse (optional - defaults to false): if enabled, Hibernate will not
    insert or update the properties
    defined by this join.
  6. optional (optional - defaults to false): if enabled, Hibernate will
    insert a row only if the properties
    defined by this join are non-null. It
    will always use an outer join to
    retrieve the properties.

For example, address information for a
person can be mapped to a separate
table while preserving value type
semantics for all properties:

<class name="Person"
    table="PERSON">

    <id name="id" column="PERSON_ID">...</id>

    <join table="ADDRESS">
        <key column="ADDRESS_ID"/>
        <property name="address"/>
        <property name="zip"/>
        <property name="country"/>
    </join>
    ...

This feature is often only useful for
legacy data models. We recommend fewer
tables than classes and a fine-grained
domain model. However, it is useful
for switching between inheritance
mapping strategies in a single
hierarchy, as explained later.

Using composition as you did is another option but it will obviously introduce another table (for the "aggregating" entity).

街道布景 2024-09-24 17:42:08

不确定这是否是答案,但 Hibernate 确实允许“复合”关系,即您将一个类嵌入到另一个类中,然后将其映射。

例如,在这里我们创建“可嵌入”类(车辆),然后将其“嵌入”到 VehicleWeapon 中:

import javax.persistence.Embeddable;

@Embeddable
public class Vehicle
{
    ...
}

嵌入此处:

@Entity
public class VehicleWeapon
{
  private long id;  
  private String name;
  private Vehicle vehicle;

  ...

    @Embedded
    public Vehicle getVehicle()
    {
      return vehicle;
    }

    public void setVehicle(Vehicle vehicle)
    {
        this.vehicle = vehicle;
    }

    ...
}

这对您的场景有帮助吗?

Not sure whether this is the answer, but Hibernate does allow for “compound” relationships, whereby you embed one class within another, and that gets mapped.

For example, here we create the "embeddable" class (Vehicle) and then "embed" it in VehicleWeapon:

import javax.persistence.Embeddable;

@Embeddable
public class Vehicle
{
    ...
}

Embedded here:

@Entity
public class VehicleWeapon
{
  private long id;  
  private String name;
  private Vehicle vehicle;

  ...

    @Embedded
    public Vehicle getVehicle()
    {
      return vehicle;
    }

    public void setVehicle(Vehicle vehicle)
    {
        this.vehicle = vehicle;
    }

    ...
}

Would that help in your scenario?

魔法少女 2024-09-24 17:42:08

使用 joincolumn 和 inverseJoincolumn 注释来连接两个表(Vehicle 和 Weapon)并将它们放入事务表(VehicleWeapon)中。
使用任何映射(onetoone、onetomany 等)通过 ondeletecascade 和 fetch 映射车辆 amd waepon 表。

use joincolumn and inverseJoincolumn annotations for join two tables (Vehicle and Weapon) and put those in to transaction table (VehicleWeapon).
use any mapping(onetoone, onetomany, etc) to map vehicle amd waepon tables with ondeletecascade and fetch.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文