Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple @ManyToOne fields pointing to same entity in JPA / Hibernate

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:

  1. Is @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?
  2. Assuming 1. is OK, how do I make the mapping bidirectional (What annotation(s) should I use in the 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;
}
like image 373
scott77777 Avatar asked Jan 25 '14 01:01

scott77777


People also ask

Can a JPA entity have multiple Onetomany associations?

You can have multiple one-to-many associations, as long as only one is EAGER.

How to map two entity with hibernate?

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.

What is difference between mappedBy and @JoinColumn?

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.

What is referencedColumnName in @JoinColumn hibernate?

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.


1 Answers

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;
like image 131
JB Nizet Avatar answered Oct 10 '22 06:10

JB Nizet