Това всъщност е добър въпрос, който си заслужава малко проучване и експериментиране. Има много начини да направите картографирането. Измислянето на по-добър дизайн всъщност ще зависи от нуждите на вашето приложение. Но ето как според мен би бил ефективен начин за прилагане на картографирането:
Ще имам 3 отделни обекта за Order , Product и Address .
Няма да приложим обичайната връзка много към много между 2-те субекта, Order и Product , където всяка страна има колекция от другата. Вместо това ще създам друг обект, който да представя връзката между Order и Product , и нека го наречем ProductOrder . Ето как са картографирани техните взаимоотношения:
Orderима връзка едно към много сProductOrder.ProductOrderима връзка много към едно сOrder.Productима връзка едно към много сProductOrder.ProductOrderима връзка много към едно сProduct.
ProductOrder Първичният ключ на 's ще се състои от първичния ключ на 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>();
...
}
PRODUCT ENTITY
@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")},
example@sqldat.com(name="ADDRESS_ID", referencedColumnName="ADDRESS_ID"))
private List<Address> addressList = new ArrayList<Address>();
...
}
@IdClass за обект ProductOrder
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)