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?
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:
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:
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
andupdatable
attributes to false should be enough.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.