I have an Order
entity that has a billingAddress
and a shippingAddress
. I also have an Address
entity. I am trying to make a single address table hold both the shipping and billing addresses, since there is nothing to differentiate them, and the billing and shipping address can be the same in one or multiple orders. I have used @ManyToOne
on the address fields in Order
, but I'm not sure of the proper way to make this bidirectional.
I have two questions:
@ManyToOne
appropriate for the address fields, since it is really an n:2 relationship that I simply am using two separate fields to represent? If not, what should I do instead?Address
entity?)? Can this be done by listing multiple columns in an annotation in Address
?Code:
@Entity
@Table(name = "orders")
public class Order {
//...
private Address shippingAddress;
private Address billingAddress;
@ManyToOne
@JoinColumn(name = "shipping_address_id", referencedColumnName = "address_id", nullable = false)
public Address getShippingAddress() {
return shippingAddress;
}
@ManyToOne
@JoinColumn(name = "billing_address_id", referencedColumnName = "address_id", nullable = false)
public Address getBillingAddress() {
return billingAddress;
}
//...
}
@Entity
@Table(name = "addresses")
public class Address {
//address1, address2, city, state, etc.
//how to link back to Orders?
private Set<Order> orders;
}
You can have multiple one-to-many associations, as long as only one is EAGER.
If you want to map the same database table to two entities, you should create a simple inheritance hierarchy. The superclass should be abstract and contain all attributes that are shared by both entities. You should map it as a mapped superclass so that it is not an entity itself.
The @JoinColumn annotation helps us specify the column we'll use for joining an entity association or element collection. On the other hand, the mappedBy attribute is used to define the referencing side (non-owning side) of the relationship.
Quoting API on referencedColumnName: The name of the column referenced by this foreign key column. Default (only applies if single join column is being used): The same name as the primary key column of the referenced table.
Regarding your first question: is it a ManyToOne?
It depends. If several orders can have the same shipping address, then it's a ManyToOne. If only one order can have a given shipping address, then it's a OneToOne. Same for billing address.
I'm not sure making the association bidirectional is a good idea. I probably wouldn't do it in this case. But if you want to make it bidirectional, then you have to make them bidirectional. You indeed have two different associations here. The mapping would thus look like the following:
@OneToMany(mappedBy = "shippingAddress")
private Set<Order> shippedOrders;
@OneToMany(mappedBy = "billingAddress")
private Set<Order> billedOrders;
or, if the association is in fact a OneToOne (see answer to the first question):
@OneToOne(mappedBy = "shippingAddress")
private Order shippedOrder;
@OneToOne(mappedBy = "billingAddress")
private Order billedOrder;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With