- Java EE 8 Application Development
- David R. Heffelfinger
- 848字
- 2021-07-02 22:05:05
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.
- Functional Python Programming
- Vue.js設計與實現
- 在最好的年紀學Python:小學生趣味編程
- 圖解Java數據結構與算法(微課視頻版)
- UI智能化與前端智能化:工程技術、實現方法與編程思想
- Python Data Analysis(Second Edition)
- SQL Server 2012數據庫管理與開發項目教程
- jQuery開發基礎教程
- Unity 5 for Android Essentials
- MySQL入門很輕松(微課超值版)
- Unity Character Animation with Mecanim
- C編程技巧:117個問題解決方案示例
- After Effects CC技術大全
- JavaScript編程精解(原書第3版)
- Learning SaltStack(Second Edition)