订单产品和Order_Line与复合键的休眠关系
好吧,所以今天我花了一整天的时间试图找出如何映射Orders,Products和OrderLine之间的关系与使用annotation所有java配置的hibernate之间的关系。订单产品和Order_Line与复合键的休眠关系
我希望OrderLine成为具有额外字段的联结表,即加入产品和订单。
订单与OrderLine有一个OneToMany关系绑定 - 一个订单有很多订单行。
每个订单有一个或多个订单行,每个订单行有一个订单,每个订单行有一个产品,每个产品可以有0个或多个订单行。
从我一直遵循的教程,有两种方法可以做到这一点。一个是@Embeddable,@EmbeddedId批注,另一个是@IdClass批注,我试过都没有成功,我会在@IdClass方法中发布自己的代码。
我的订单类
@Entity
@Table(name="orders")
public class Order {
@Id
@Column(name = "order_id")
@OneToMany(fetch = FetchType.EAGER, mappedBy = "order")
private Set<OrderLine> orderLines = new HashSet<>();
...some extra properties relevant to all orders
public Order(){}
...setters/getters
}
我的产品类
@Entity
@Table(name="products")
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "product_id")
public Integer product_id; // primary key
@OneToMany(fetch = FetchType.EAGER, mappedBy = "product")
private Set<OrderLine> orderLines = new HashSet<>();
...other properties
public Product() {
}
...setters/getters
}
这里是我的订单行类
@Entity
@IdClass(OrderLineId.class)
@Table(name="order_line")
public class OrderLine implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "product_id", insertable= false, updatable= false)
public Integer product_id;
@Id
@Column(name = "order_id", insertable= false, updatable= false)
public Integer order_id;
@ManyToOne
@JoinColumn(name = "product_id", insertable = false, updatable = false)
private Product product;
@ManyToOne
@JoinColumn(name = "order_id", insertable = false, updatable = false)
private Order order;
@Column(name = "product_quantity", unique = false, nullable = false)
private int productQuantity;
...additional fields associated with each OrderLine
最后我OrderLineId实施
public class OrderLineId implements Serializable {
private static final long serialVersionUID = 1L;
private Integer order_id;
private Integer product_id;
public OrderLineId(){}
public OrderLineId(Integer order_id, Integer product_id) {
this.order_id = order_id;
this.product_id = product_id;
}
@Column(name = "order_id")
public Integer getOrder() {
return this.order_id;
}
public void setOrder(Integer order_id) {
this.order_id = order_id;
}
@Column(name = "product_id")
public Integer getProduct() {
return this.product_id;
}
public void setProduct(Integer product_id) {
this.product_id = product_id;
}
@Override
public int hashCode() {
return order_id + product_id;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof OrderLineId){
OrderLineId orderLineId = (OrderLineId) obj;
return orderLineId.order_id == order_id && orderLineId.product_id == product_id;
}
return false;
}
}
这里是我得到
MySQLSyntaxErrorException: Unknown column 'orderlines0_.order' in 'field list'
例外,当我访问以下
@RequestMapping(value = "/testorder", method = RequestMethod.GET)
public ModelAndView testOrder(){
Order order = orderService.findOrderById(23);
Product product = productService.findProduct(2);
OrderLine ol = new OrderLine(product, order);
ol.setSize("large");
ol.setProductQuantity(30);
orderService.saveOrderLine(ol);
return null;
}
终点可以请别人帮我,这是推动我疯了....
谢谢
好吧,我想通了 - 我结束了使用嵌入的方法,而不是基于这个家伙的优秀教程^ h ere
他经历来实现多对多assosiations 3个主要途径 - 一个简单的只有联合表的表,一个联结表(带有附加字段),这是我需要实现的方法,最后是一个不太流行的方法,其中类被映射为组件。
经过你的问题和代码后,我认为你的设计错了。
你说
想要的OrderLine要结合表有额外的字段,即加入产品和订单。
但是,您的OrderLine类只有两个变量Order和Product。
如果我没有错,你真正需要的是多对多表。
你的表order_line
将包含两列order_id
和product_id
,分别为外键表orders
和products
。
您的订单类将是:
@Entity
@Table(name="orders")
public class Order {
@Id
//id of table Order
@ManyToMany(
targetEntity = Product.class,
cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
@JoinTable(name = "order_line",
joinColumns =
@JoinColumn(name = "order_id", nullable = false, updatable = false),
inverseJoinColumns =
@JoinColumn(name = "product_id", nullable = false, updatable = false))
public Set<Product> products= new HashSet(0);
...some extra properties relevant to all orders
public Order(){}
...setters/getters
}
你的产品类别将如下所示:
@Entity
@Table(name="products")
public class Product implements Serializable {
@Id
@Column(name = "product_id")
public Integer product_id; // primary key
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "products", targetEntity = Order.class) private Set<Order> order = new HashSet<>();
...other properties
public Product() {
}
...setters/getters
}
正如你所看到的,从订单实体即可获得“产品”,从产品的实体,您可以得到'订单'。这应该服务于你的目的。无需使用'OrderLine'类。
代码中的其他主要错误: - @Id用于表示主键。您已经多次为单个类使用@Id。 - 在给定的'Order'类@Id中,@Id与@OneToMany一起使用,这将不起作用。
如果您确实需要的是多对多的表格,则提供的代码将对您有所帮助。
我得到了它在我的最后一次尝试,昨晚做这个变化
在订单行我删除了PRODUCT_ID和ORDER_ID领域工作,并放置@Id注释在两个多对一的关系,像这样
@Entity
@IdClass(OrderLineId.class)
@Table(name="order_line")
public class OrderLine implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@ManyToOne
@JoinColumn(name = "product_id", insertable = false, updatable = false)
private Product product;
@Id
@ManyToOne
@JoinColumn(name = "order_id", insertable = false, updatable = false)
private Order order;
@Column(name = "product_quantity", unique = false, nullable = false)
private int productQuantity;
...additional fields associated with each OrderLine
我不认为这个工作正常,但正确的表格正确值已更新,这是否有效?
谢谢
您好,感谢您的评论。那么这就是我原来的代码,但是我需要在函数表中有额外的字段,所以一个简单的ManyToMany关联将不起作用 - OrderLine将有大约6个与它相关的属性,'product_size','product_color',等现在有意义吗?还有,@Id的多次使用是特意完成的,我构建的教程是在构造从其他实体主键派生的组合键时执行的。谢谢 – 2014-11-25 18:10:37