Many-to-many relationships

In the CUSTOMERDB database, there is a many-to-many relationship between the ORDERS table and the ITEMS table. We can map this relationship by adding a new Collection<Item> field to the Order entity and decorating it with the @ManyToMany annotation:

package net.ensode.javaee8book.entityrelationship.entity; 
 
import java.util.Collection; 
 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.JoinTable; 
import javax.persistence.ManyToMany; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 
 
@Entity 
@Table(name = "ORDERS") 
public class Order 
{ 
  @Id 
  @Column(name = "ORDER_ID") 
  private Long orderId; 
 
  @Column(name = "ORDER_NUMBER") 
  private String orderNumber; 
 
  @Column(name = "ORDER_DESCRIPTION") 
  private String orderDescription; 
 
  @ManyToOne 
  @JoinColumn(name = "CUSTOMER_ID") 
  private Customer customer; 
 
  @ManyToMany 
@JoinTable(name = "ORDER_ITEMS",

joinColumns = @JoinColumn(name = "ORDER_ID",

referencedColumnName = "ORDER_ID"),

inverseJoinColumns = @JoinColumn(name = "ITEM_ID",

referencedColumnName = "ITEM_ID"))
private Collection<Item> items; public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer = customer; } public String getOrderDescription() { return orderDescription; } public void setOrderDescription(String orderDescription) { this.orderDescription = orderDescription; } public Long getOrderId() { return orderId; } public void setOrderId(Long orderId) { this.orderId = orderId; } public String getOrderNumber() { return orderNumber; } public void setOrderNumber(String orderNumber) { this.orderNumber = orderNumber; } public Collection<Item> getItems()
{

return items;

}
public void setItems(Collection<Item> items)
{
this.items = items;

}
}

As we can see in the preceding code, in addition to being decorated with the @ManyToMany annotation, the items field is also decorated with the @JoinTable annotation. Like its name suggests, this annotation lets the application server know what table is used as a join table to create the many-to-many relationship between the two entities. This annotation has three relevant elements: the name element, which defines the name of the join table, and the joinColumns and inverseJoinColumns elements, which define the columns that serve as foreign keys in the join table pointing to the entities' primary keys. Values for the joinColumns and inverseJoinColumns elements are yet another annotation: the @JoinColumn annotation. This annotation has two relevant elements: the name element, which defines the name of the column in the join table, and the referencedColumnName element, which defines the name of the column in the entity table.

The Item entity is a simple entity mapping to the ITEMS table in the CUSTOMERDB database:

package net.ensode.javaee8book.entityrelationship.entity; 
 
import java.util.Collection; 
 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.ManyToMany; 
import javax.persistence.Table; 
 
@Entity 
@Table(name = "ITEMS") 
public class Item 
{ 
  @Id 
  @Column(name = "ITEM_ID") 
  private Long itemId; 
 
  @Column(name = "ITEM_NUMBER") 
  private String itemNumber; 
 
  @Column(name = "ITEM_SHORT_DESC") 
  private String itemShortDesc; 
 
  @Column(name = "ITEM_LONG_DESC") 
  private String itemLongDesc; 
 
  @ManyToMany(mappedBy="items") 
private Collection<Order> orders;
public Collection<Order> getOrders()

{

return orders;

}

public void setOrders(Collection<Order> orders)
{
this.orders = orders;

}
//additional setters and getters removed for brevity }

Just like one-to-one and one-to-many relationships, many-to-many relationships can be unidirectional or bidirectional. Since we would like the many-to-many relationship between the Order and Item entities to be bidirectional, we added a Collection<Order> field and decorated it with the @ManyToMany annotation. Since the corresponding field in the Order entity already has the join table defined, it is not necessary to do it again here. The entity containing the @JoinTable annotation is said to own the relationship; in a many-to-many relationship, either entity can own the relationship. In our example, the Order entity owns it, since its Collection<Item> field is decorated with the @JoinTable annotation.

Just like with one-to-one and one-to-many relationships, the @ManyToMany annotation in the non-owning side of a bidirectional many-to-many relationship must contain a mappedBy element indicating which field in the owning entity defines the relationship.

Now that we have seen the changes necessary to establish a bidirectional many-to-many relationship between the Order and Item entities, we can see the relationship in action in the following example:

package net.ensode.javaee8book.entityrelationship.namedbean; 
 
import java.util.ArrayList; 
import java.util.Collection; 
import javax.annotation.Resource; 
import javax.enterprise.context.RequestScoped; 
import javax.inject.Named; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import javax.transaction.HeuristicMixedException; 
import javax.transaction.HeuristicRollbackException; 
import javax.transaction.NotSupportedException; 
import javax.transaction.RollbackException; 
import javax.transaction.SystemException; 
import javax.transaction.UserTransaction; 
import net.ensode.javaee8book.entityrelationship.entity.Item; 
import net.ensode.javaee8book.entityrelationship.entity.Order; 
 
@Named 
@RequestScoped 
public class ManyToManyRelationshipDemoBean { 
 
    @PersistenceContext 
    private EntityManager entityManager; 
 
    @Resource 
    private UserTransaction userTransaction; 
 
    public String updateDatabase() { 
        String retVal = "confirmation"; 
 
        Order order; 
        Collection<Item> items = new ArrayList<Item>(); 
        Item item1 = new Item(); 
        Item item2 = new Item(); 
 
        item1.setItemId(1L); 
        item1.setItemNumber("BCD1234"); 
        item1.setItemShortDesc("Notebook Computer"); 
        item1.setItemLongDesc("64 bit Quad core CPU, 4GB memory"); 
 
        item2.setItemId(2L); 
        item2.setItemNumber("CDF2345"); 
        item2.setItemShortDesc("Cordless Mouse"); 
        item2.setItemLongDesc("Three button, infrared, " 
                + "vertical and horizontal scrollwheels"); 
 
        items.add(item1); 
        items.add(item2); 
 
        try { 
            userTransaction.begin(); 
 
            entityManager.persist(item1);    
entityManager.persist(item2);

order = entityManager.find(Order.class, 1L);

order.setItems(items);

entityManager.persist(order);
userTransaction.commit(); } catch (NotSupportedException | SystemException | SecurityException | IllegalStateException | RollbackException | HeuristicMixedException | HeuristicRollbackException e) { retVal = "error"; e.printStackTrace(); } return retVal; } }

The preceding code creates two instances of the Item entity and populates them with some data. It then adds these two instances to a collection. A transaction is then started and the two Item instances are persisted to the database. Then an instance of the Order entity is retrieved from the database. The setItems() method of the Order entity instance is then invoked, passing the collection containing the two Item instances as a parameter. The Customer instance is then persisted into the database. At this point, two rows are created behind the scenes to the ORDER_ITEMS table, which is the join table between the ORDERS and ITEMS tables.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.227.72.15