Java JPA ManyToMany联接表的所有属性都是PK
我使用的是Hibernate 3.3.1,并且在建模方面也遵循这一点,但是我在创建带有额外属性的联接表时遇到了问题 这是Java JPA ManyToMany联接表的所有属性都是PK,java,hibernate,jpa-2.0,Java,Hibernate,Jpa 2.0,我使用的是Hibernate 3.3.1,并且在建模方面也遵循这一点,但是我在创建带有额外属性的联接表时遇到了问题 这是订单和产品表之间的多对多关系。联接表是订单明细表。我采用了上述方法 现在我有了实体 @Entity @Table(name = "Orders") public class Order { @OneToMany(mappedBy="order") private List<OrderDetail> orderItems; } 及 我使用Apache
订单
和产品
表之间的多对多关系。联接表是订单明细表。我采用了上述方法
现在我有了实体
@Entity
@Table(name = "Orders")
public class Order {
@OneToMany(mappedBy="order")
private List<OrderDetail> orderItems;
}
及
我使用ApacheDerby进行测试,但生成的表结构有问题
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版本中工作,但可以肯定的是,它在从未有过的版本中工作。无论如何都值得一试。如果您想使用JPA2.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;
}
下面的代码似乎可以根据需要生成表,我已经在MySQL上对其进行了测试(只是创建表,而不是CRUD):
嗨,Mikko,啊,这只是一个想法,因为我仍然是JPA的初学者。我开始认为@ManyToMany注释似乎更像是一个细微差别,当你可以手动操作时?你不这么认为吗?我的理解有点肤浅,但这是我的印象。在所有情况下,我都能正确思考,知道,没有太多的地图是可能的。当关系的本质要求时,我强烈地倾向于总是使用多对多,因为它更干净,生成的代码更少。
public class OrderDetailId implements Serializable {
private Long orderId;
private Long productId;
}
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);
@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;
}
@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;
}
@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
}
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)