[英]JPA ManyToMany Join Table has all attributes as PK
我正在使用Hibernate 3.3.1並且正在建模這個示例表結構 ,但是我在創建具有額外屬性的連接表時遇到了麻煩。
它是Order
和Product
表之間的多對多關系。 連接表是Order Detail
表。 我按照這里提到的方法。
現在我有了實體
@Entity
@Table(name = "Orders")
public class Order {
@OneToMany(mappedBy="order")
private List<OrderDetail> orderItems;
}
和
@Entity
@Table(name="PRODUCTS")
public class Product {
@OneToMany(mappedBy="product")
private List<OrderDetail> orderItems;
}
和
@Entity
@IdClass(OrderDetail.class)
@Table(name = "ORDER_DETAIL")
public class OrderDetail implements Serializable {
@Id
@Column(name="ORDER_ID")
private Long orderId;
@Id
@Column(name="PRODUCT_ID")
private Long productId;
@Column(name = "PRICE")
private double price;
@Column(name = "LAST_UPDATED_TIME")
private Date lastUpdatedTime;
@ManyToOne
@JoinColumn(name = "ORDER_ID")
private Order order;
@ManyToOne
@JoinColumn(name = "PRODUCT_ID")
private Product product;
}
和
public class OrderDetailId implements Serializable {
private Long orderId;
private Long productId;
}
我使用Apache Derby進行測試,但是我遇到了生成的表結構的問題。
CREATE TABLE ORDER_DETAIL (
PRODUCT_ID BIGINT NOT NULL,
ORDER_ID BIGINT NOT NULL,
LAST_UPDATED_TIME TIMESTAMP NOT NULL,
PRICE DOUBLE NOT NULL
);
CREATE INDEX SQL120323142938020 ON ORDER_DETAIL (PRODUCT_ID ASC);
CREATE UNIQUE INDEX SQL120323142937810 ON ORDER_DETAIL (PRODUCT_ID ASC, ORDER_ID ASC, LAST_UPDATED_TIME ASC, PRICE ASC);
ALTER TABLE ORDER_DETAIL ADD CONSTRAINT SQL120323142937810 PRIMARY KEY (PRODUCT_ID, ORDER_ID, LAST_UPDATED_TIME, PRICE);
ALTER TABLE ORDER_DETAIL ADD CONSTRAINT FK4A94AA82CC6D989A FOREIGN KEY (PRODUCT_ID)
REFERENCES PRODUCTS (PROD_ID);
它似乎已創建我的所有列作為主鍵。 為什么會這樣?
您使用實體的類作為IdClass的參數。 這是不正確的。 應使用Id類。 另外,不需要在連接實體中用於id的單獨字段。
去尋找下面的代碼。 我不能保證它可以在如此舊的Hibernate版本中運行,但絕對可以肯定。 無論如何都值得嘗試。 如果你想使用JPA 2.0功能,更新到至少3.5.X版本(或者更確切地說是更新版本)也不會有什么壞處。 為了節省空間,剝離了構造者/平等等。
@Entity
@Table(name = "Orders")
public class Order {
@Id Long id;
@OneToMany(mappedBy="order")
private List<OrderDetail> orderItems;
}
@Entity
@Table(name="PRODUCTS")
public class Product {
@Id Long id;
@OneToMany(mappedBy="product")
private List<OrderDetail> orderItems;
}
@Entity
@IdClass(OrderDetailId.class)
@Table(name = "ORDER_DETAIL")
public class OrderDetail implements Serializable {
@Id @ManyToOne @JoinColumn(name = "ORDER_ID")
private Order order;
@Id @ManyToOne @JoinColumn(name = "PRODUCT_ID")
private Product product;
@Column(name = "PRICE") private double price;
//Maybe you also want to use @TemporalType here
@Column(name = "LAST_UPDATED_TIME") private Date lastUpdatedTime;
}
public class OrderDetailId implements Serializable {
private Long order;
private Long product;
}
更新15/08/2017在JPA 2.1及更高版本中,您不需要為復合ID添加類,您可以這樣做:
@Entity
@Table(name = "ORDER_DETAIL")
public class OrderDetail implements Serializable {
@Id @ManyToOne @JoinColumn(name = "ORDER_ID")
private Order order;
@Id @ManyToOne @JoinColumn(name = "PRODUCT_ID")
private Product product;
@Column(name = "PRICE") private double price;
//Maybe you also want to use @TemporalType here
@Column(name = "LAST_UPDATED_TIME") private Date lastUpdatedTime;
}
下面的代碼似乎根據需要生成表,我在MySQL上測試過它(只是表創建,而不是CRUD):
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "orderDetailId.order")
private List<OrderDetail> orderItems;
//get set …..
}
@Entity
@Table(name="products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToMany(mappedBy = "orderDetailId.product")
private List<OrderDetail> orderItems;
//get set ……
}
@Entity
@Table(name = "order_detail")
public class OrderDetail {
@Id
private OrderDetailId orderDetailId;
private double price;
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdatedTime;
//get set ….
}
@Embeddable
public class OrderDetailId implements Serializable{
private Order order;
private Product product;
@ManyToOne(fetch=FetchType.LAZY)
@Access(AccessType.PROPERTY)
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
@ManyToOne(fetch=FetchType.LAZY)
@Access(AccessType.PROPERTY)
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}
//hash code equals override
}
Hibernate DEBUG詳細信息如下
DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - create table order_detail (lastUpdatedTime datetime, price double precision not null, product_id bigint, order_id bigint, primary key (order_id, product_id)) ENGINE=InnoDB
DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - create table orders (id bigint not null auto_increment, primary key (id)) ENGINE=InnoDB
DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - create table products (id bigint not null auto_increment, primary key (id)) ENGINE=InnoDB
DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table order_detail add index FK23AE5A622128CF91 (order_id), add constraint FK23AE5A622128CF91 foreign key (order_id) references orders (id)
DEBUG: org.hibernate.tool.hbm2ddl.SchemaUpdate - alter table order_detail add index FK23AE5A62EB201631 (product_id), add constraint FK23AE5A62EB201631 foreign key (product_id) references products (id)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.