我有一个非常简单的DB模式,经典的顺序--(一对多)--> OrderItem <--(多对一)--产品
但是,当我使用SchemaGen生成DDL时,它会创建一个额外的层orders_orders_item和product_orders_item,实际上添加了一个冗余层的关联表:
create table orders (order_id bigint not null auto_increment, order_amout varchar(255), primary key (order_id)) engine=InnoDB;
create table orders_item (orders_item_id bigint not null auto_increment, order_amount integer, product_id bigint not null, primary key (orders_item_id)) engine=InnoDB;
create table orders_orders_item (OrderEntity_order_id bigint not null, orderItems_orders_item_id bigint not null) engine=InnoDB;
create table product (id bigint not null auto_increment, name varchar(255), price decimal(19,2), primary key (id)) engine=InnoDB;
create table product_orders_item (ProductEntity_id bigint not null, orders_orders_item_id bigint not null) engine=InnoDB;它似乎认为orders和orders_item以及product与orders_item之间有很多关联。
为什么会发生这种情况?
我的实体类如下所示:
命令:
@Entity
@Table(name = "orders")
public class OrderEntity {
@Id
@Column(name = "order_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@OneToMany
private List<OrderItemEntity> orderItems;
protected OrderEntity() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public List<OrderItemEntity> getOrderItems() {
return orderItems;
}
public void setOrderItems(List<OrderItemEntity> orderItems) {
this.orderItems = orderItems;
}
}订单项目:
@Entity
@Table(name = "orders_item")
public class OrderItemEntity {
@Id
@Column(name = "orders_item_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "product_id", nullable = false, updatable = false)
private ProductEntity product = new ProductEntity();
@Column(name = "order_amount")
private int amount;
protected OrderItemEntity() {
}
public OrderItemEntity(ProductEntity product, int amount) {
super();
this.product = product;
this.amount = amount;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public ProductEntity getProduct() {
return product;
}
public void setProduct(ProductEntity product) {
this.product = product;
}
}产品:
@Entity
@Table(name = "product")
public class ProductEntity {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@OneToMany
private List<OrderItemEntity> orders = new ArrayList<>();
@Column(name = "name")
private String name;
@Column(name = "price")
private BigDecimal price;
protected ProductEntity() {
}
public ProductEntity(String name) {
this.name = name;
}
public ProductEntity(String name, BigDecimal price) {
super();
this.name = name;
this.price = price;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}发布于 2021-02-21 13:26:43
orders_orders_item表:由于您没有指定@JoinColumn,而不是只指定一个外键,因此将创建一个包含两个外键的额外表。
orders_orders_item (OrderEntity_order_id, orderItems_orders_item_id) 要解决这个问题,应该将@JoinColumn注释添加到OrderEntity中。
@Entity
@Table(name = "orders")
public class OrderEntity {
//...
@OneToMany
@JoinColumn(name = "order_id")
private List<OrderItemEntity> orderItems;
}使用此映射,将只向order_id表添加一个orders_item列。不需要不必要地创建orders_orders_item表
product_orders_item表:orders_item与product之间存在双向关系。您在@JoinColumn端指定了orders_item。这导致在product_id表上创建了orders_item列,这是正确的。
但是另一方面,由于您没有指定mappedBy,而且它是一个双向关系,DB试图通过创建product_orders_item表来创建链接。
您应该将mappedBy属性添加到orders字段。
@Entity
@Table(name = "product")
public class ProductEntity {
// ...
@OneToMany (mappedBy="product")
private List<OrderItemEntity> orders = new ArrayList<>();
}这表明在product和orders_item之间已经创建了双向关系(不需要映射orders字段)。不需要额外的表创建,等等。多亏了@JoinColumn,在orders_item表中创建了product_id列。
发布于 2021-02-21 14:50:12
你们的协会:
@Entity
public class OrderEntity {
@OneToMany
private List<OrderItemEntity> orderItems;
// ...
}
@Entity
public class ProductEntity {
@OneToMany
private List<OrderItemEntity> orders = new ArrayList<>();
// ...
}是单向 @OneToMany。因此,正如文档中所述:
当使用单向
@OneToMany关联时,Hibernate需要在两个连接实体之间使用一个链接表。
您可以通过添加@JoinColumn注释来更正它,因为它在@Hülya回答中提到过。(在JPA2.0中添加)。但是,双向 @OneToMany在管理集合持久性状态时效率要高得多。每个元素删除只需要一个更新(其中外键列设置为NULL)。
https://stackoverflow.com/questions/66302300
复制相似问题