【问题标题】:Hibernate: how do I map one to one where B is a property of A?Hibernate:如何在 B 是 A 的属性的情况下一对一映射?
【发布时间】:2014-08-28 18:28:43
【问题描述】:

我有一个 A 类,具有 B 类的属性。

A 的 SQL 表对 B 一无所知。

B 的 SQL 表包含 A 的外键。

如何映射(在 hbm.xml 中)使 B 成为 A 的属性?我知道如何使用 Set 来做到这一点:

<set name="b" table="B" cascade"all-delete-orphan">
    <key column="a_id">
    <composite-element class="B">
        <property name="bProp" column="b_prop" type="string"/>
    </composite-element>
</set>

问题是,B 不是 A 的集合。而只是一个元素。我该如何进行映射?


编辑:澄清一下,我的用例类似于http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/associations.html#assoc-unidirectional-m21,除了代替:

create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )

我有:

create table Person ( personId bigint not null primary key )
create table Address ( personId bigint, addressId bigint not null primary key )

但是,我希望实际的地址类不包含对 Person 的任何引用:

class Person {
    Address address;
}

class Address {
    int id;
}

【问题讨论】:

  • 在您的示例中,由于子类 (Address) 具有对父类 (Person) 的外键引用,这实际上是从 Person 到 Address 的一对多关系。该模式明确表示一个人可能有多个地址,但每个地址只属于一个人。
  • 是的……我明白了。我已经和我的队友一起提出了这个问题,但似乎太多的代码依赖于保持原样的 db 表。是否仍然可以将其映射为单个元素而不是 Set?
  • 在 ORM 中以“错误”的方式映射关系很尴尬。见stackoverflow.com/questions/2452987/…
  • 同意。我正在推动重新考虑这一点,但就像我说我的团队正在推迟,因为它涉及很多代码。你是在告诉我没有办法做我想做的事吗?
  • 不,当然有办法(见我的回答),只是笨拙。

标签: java sql hibernate


【解决方案1】:

我不是特别喜欢这个解决方案,但是您可以通过使用几个包装方法来解决这个问题。为未映射的属性创建一个假的 getter/setter 对,为您提供所需的接口。因此:

public class Person {
    private List<Address> addresses;
    // properties, real getters and setters

    public Address getAddress() {
        if (this.addresses == null || this.addresses.isEmpty()) {
            return null;
        }
        return this.addresses.get(0);
    }

    public void setAddress(Address address) {
        if (this.addresses == null) {
            this.addresses = new ArrayList<Address>();
        }
        this.addresses.clear();
        this.addresses.add(address);
    }
}

【讨论】:

  • 哎呀,这个解决方案绝对不是太疯狂,但总比没有好。谢谢大佬。
【解决方案2】:

如果其他人遇到这种情况,我终于想通了。只需使用

映射第二个表
<join table="Address">
    <key column="personId">
        <component name="address" class="Address">
            <property name="id" column="addressId" type="int" />
        </component>
    </key>
</join>

【讨论】:

    猜你喜欢
    • 2014-08-11
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2013-06-16
    • 2021-08-18
    • 2012-04-21
    相关资源
    最近更新 更多