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

2022-09-02 13:47:22

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

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

(为简洁起见,省略了 getter/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

我试图添加到所有字段,但似乎这并不胜过。@TransientAddress@AttributeOverride@Transient

有什么解决方法吗?


答案 1

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

private PartialAddress billingAddress;

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

否则,我已经为这个问题提出了一个有点丑陋的解决方法,也许它也会对你有用。我没有将字段映射到实际列,而是返回一个 SQL 空常量:

@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上运行。我只在只读对象上测试了它。但是,从理论上讲,将 和 属性设置为 false 应该就足够了。insertableupdatable


答案 2

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

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


推荐