これは実際には、調査と実験に値する良い質問です。マッピングを行う方法はたくさんあります。より良い設計を考え出すことは、実際にはアプリケーションのニーズに依存します。しかし、マッピングを実装するための効果的な方法は次のとおりです。
Order
用に3つの個別のエンティティがあります 、Product
およびAddress
。
2つのエンティティ間の通常の多対多の関係であるOrder
は実装しません。 およびProduct
、それぞれの側にもう一方のコレクションがあります。代わりに、Order
間の関係を表す別のエンティティを作成します およびProduct
、ProductOrder
という名前を付けましょう 。それらの関係がどのようにマッピングされるかは次のとおりです。
Order
ProductOrder
と1対多の関係にあります 。-
ProductOrder
Order
と多対1の関係にあります 。 Product
ProductOrder
と1対多の関係にあります 。-
ProductOrder
Product
と多対1の関係にあります 。
ProductOrder
の主キーは、Order
の主キーで構成されます。 およびProduct
の主キー -したがって、これは複合キーになります。したがって、@IdClass
を使用する必要があります 複合キーをマッピングします。
さて、これが多対多の関係の中で多対多を達成するための秘訣です:
ProductOrder
Address
と多対多の関係にあります 。
上記の各エンティティのサンプルコードを参照してください:
注文エンティティ
@Entity
@Table(name = "ORDERS")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ORDER_ID")
private Long id;
private int quantity;
@OneToMany(mappedBy = "order")
private List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
...
}
製品エンティティ
@Entity
@Table(name="PRODUCT")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PRODUCT_ID")
private Long id;
private String name;
@OneToMany(mappedBy = "product")
private List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
...
}
アドレスエンティティ
@Entity
@Table(name="ADDRESS")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ADDRESS_ID")
private Long id;
private String state;
@ManyToMany(mappedBy = "addressList")
private List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
...
}
製品注文エンティティ
@Entity
@Table(name="PRODUCT_ORDER")
@IdClass(ProductOrderId.class)
public class ProductOrder {
@Id
@ManyToOne
@JoinColumn(name="ORDER_ID")
private Order order;
@Id
@ManyToOne
@JoinColumn(name="PRODUCT_ID")
private Product product;
@ManyToMany
@JoinTable(name="PRODUCT_ORDER_ADDRESS",
joinColumns={@JoinColumn(name="ORDER_ID", referencedColumnName="ORDER_ID"),
@JoinColumn(name="PRODUCT_ID", referencedColumnName="PRODUCT_ID")},
[email protected](name="ADDRESS_ID", referencedColumnName="ADDRESS_ID"))
private List<Address> addressList = new ArrayList<Address>();
...
}
@IdClassforProductOrderエンティティ
public class ProductOrderId {
private Long order;
private Long product;
...
}
エンティティを作成して永続化するためのサンプルコードは次のとおりです。
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Order order = new Order();
order.setQuantity(10);
em.persist(order);
Product product = new Product();
product.setName("Coffee");
em.persist(product);
Address address = new Address();
address.setState("CA");
em.persist(address);
ProductOrder productOrder = new ProductOrder();
productOrder.setOrder(order);
productOrder.setProduct(product);
productOrder.getAddressList().add(address);
address.getProductOrderList().add(productOrder);
em.persist(productOrder);
em.getTransaction().commit();
MySQLデータベースでスキーマが生成された方法は次のとおりです。
Hibernate:
create table ADDRESS (
ADDRESS_ID bigint not null auto_increment,
state varchar(255),
primary key (ADDRESS_ID)
)
Hibernate:
create table ORDERS (
ORDER_ID bigint not null auto_increment,
quantity integer not null,
primary key (ORDER_ID)
)
Hibernate:
create table PRODUCT (
PRODUCT_ID bigint not null auto_increment,
name varchar(255),
primary key (PRODUCT_ID)
)
Hibernate:
create table PRODUCT_ORDER (
ORDER_ID bigint,
PRODUCT_ID bigint,
primary key (ORDER_ID, PRODUCT_ID)
)
Hibernate:
create table PRODUCT_ORDER_ADDRESS (
ORDER_ID bigint not null,
PRODUCT_ID bigint not null,
ADDRESS_ID bigint not null
)
Hibernate:
alter table PRODUCT_ORDER
add constraint FK_sl39bwx60xjbvoiujpaes74ty
foreign key (ORDER_ID)
references ORDERS (ORDER_ID)
Hibernate:
alter table PRODUCT_ORDER
add constraint FK_n0i7uxq6rxsc0mcred1cds4m9
foreign key (PRODUCT_ID)
references PRODUCT (PRODUCT_ID)
Hibernate:
alter table PRODUCT_ORDER_ADDRESS
add constraint FK_kad6crei9lgrv1nuuuff42vs8
foreign key (ADDRESS_ID)
references ADDRESS (ADDRESS_ID)
Hibernate:
alter table PRODUCT_ORDER_ADDRESS
add constraint FK_hpx0e467dvpqi5i6kxmujns2b
foreign key (ORDER_ID, PRODUCT_ID)
references PRODUCT_ORDER (ORDER_ID, PRODUCT_ID)