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

时间:2011-08-10 19:10:56

标签: java hibernate jpa annotations

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

我们有一个可嵌入的类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

有没有解决方法呢?

2 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:7)

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

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应该足够了。