使用 Hibernate/JPA 根据具体情况从 @Embedded 属性中排除字段

发布于 2024-11-28 16:47:37 字数 1467 浏览 2 评论 0原文

我正在将 Hibernate hbm.xml 文件中的一些类迁移到 JPA 注释。

我们有一个可在多个地方使用的嵌入类Address。每个地点都使用 Address 中属性的不同子集。

(为简洁起见,省略了 getters/setters)

@Embeddable
public class Address {
  String email;
  String address;
  String city; 
  String state;
  String zip;
  String country;
}

@Entity
@Table(name="customer")
public class Customer {
  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name="address", column=@Column(name="ship_addr"),
    @AttributeOverride(name="city", column=@Column(name="ship_city"),
    @AttributeOverride(name="state", column=@Column(name="ship_state"),
    @AttributeOverride(name="zip", column=@Column(name="ship_zip"),
    @AttributeOverride(name="country", column=@Column(name="ship_country")
  })
  Address shippingAddress;

  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name="address", column=@Column(name="bill_addr"),
    @AttributeOverride(name="city", column=@Column(name="bill_city"),
    @AttributeOverride(name="state", column=@Column(name="bill_state"),
    @AttributeOverride(name="zip", column=@Column(name="bill_zip")
  })
  Address billingAddress;
}

请注意,在这个人为的示例中,shippingAddress 使用了 Address.country,但 billingAddress 没有;他们都不使用Address.email。

问题是 Hibernate 正在为我未明确提供的任何列推断 @Column 标记。

我尝试将 @Transient 添加到所有 Address 字段,但似乎 @AttributeOverride 并不胜过 @Transient

有什么解决方法吗?

I am migrating some classes in a Hibernate hbm.xml file to JPA annotations.

We have an embeddable class Address that is used in several places. Each place uses a different subset of the properties in Address.

(getters/setters omitted for brevity)

@Embeddable
public class Address {
  String email;
  String address;
  String city; 
  String state;
  String zip;
  String country;
}

@Entity
@Table(name="customer")
public class Customer {
  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name="address", column=@Column(name="ship_addr"),
    @AttributeOverride(name="city", column=@Column(name="ship_city"),
    @AttributeOverride(name="state", column=@Column(name="ship_state"),
    @AttributeOverride(name="zip", column=@Column(name="ship_zip"),
    @AttributeOverride(name="country", column=@Column(name="ship_country")
  })
  Address shippingAddress;

  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name="address", column=@Column(name="bill_addr"),
    @AttributeOverride(name="city", column=@Column(name="bill_city"),
    @AttributeOverride(name="state", column=@Column(name="bill_state"),
    @AttributeOverride(name="zip", column=@Column(name="bill_zip")
  })
  Address billingAddress;
}

Note that in this contrived example, shippingAddress uses Address.country, but billingAddress does not; and neither of them use Address.email.

The problem is that Hibernate is inferring @Column tags for any column where I haven't explicitly provided one.

I tried adding @Transient to all the Address fields, but it appears that @AttributeOverride does not trump @Transient.

Is there any workaround for this?

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

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

发布评论

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

评论(2

德意的啸 2024-12-05 16:47:37

我的建议是创建一个名为 PartialAddress/NationalAddress/BillingAddress 的新实体。这将仅用于 JPA 映射,而不是在客户界面上公开:

private PartialAddress billingAddress;

public Address getBillingAddress() {
    return billingAddress.toAddress();
}

否则,我为这个问题想出了一个有点丑陋的解决方法,也许它也适合您。我没有将字段映射到实际列,而是返回 SQL null 常量:

@Embedded
@AttributeOverrides({
    @AttributeOverride(name="address", column=@Column(name="bill_addr"),
    @AttributeOverride(name="city", column=@Column(name="bill_city"),
    @AttributeOverride(name="state", column=@Column(name="bill_state"),
    @AttributeOverride(name="zip", column=@Column(name="bill_zip"),
    @AttributeOverride(name="country", column=@Column(name="bill_id + null"),
})
Address billingAddress;

我使用的是 Oracle 和 EclipseLink,也适用于 Hibernate 3.6。我只在只读对象上测试过它。不过,从理论上讲,将 insertableupdatable 属性设置为 false 就足够了。

My advice would be to create a new entity called PartialAddress/NationalAddress/BillingAddress. This would be used only for the JPA mapping, and not exposed on the Customer interface:

private PartialAddress billingAddress;

public Address getBillingAddress() {
    return billingAddress.toAddress();
}

Otherwise, I have come up with a somewhat ugly workaround for this problem, maybe it will work for you as well. Instead of mapping the field to a real column, I return a SQL null constant:

@Embedded
@AttributeOverrides({
    @AttributeOverride(name="address", column=@Column(name="bill_addr"),
    @AttributeOverride(name="city", column=@Column(name="bill_city"),
    @AttributeOverride(name="state", column=@Column(name="bill_state"),
    @AttributeOverride(name="zip", column=@Column(name="bill_zip"),
    @AttributeOverride(name="country", column=@Column(name="bill_id + null"),
})
Address billingAddress;

I'm using Oracle and EclipseLink, works on Hibernate 3.6 as well. And I've only tested it on read-only objects. Though, theoretically, setting the insertable and updatable attributes to false should be enough.

你的心境我的脸 2024-12-05 16:47:37

我认为注释不可能“忽略”嵌入对象中地址中的字段。

解决方法是创建一个不带电子邮件的基本类型地址和一个带有电子邮件字段的扩展地址(地址的子类)。

I don't think it is possible with annotations to "ignore" a field from address in your embedded objects.

A workaround is to create a base type Address without email and an ExtendedAddress (subclass of Address) with the field email.

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