订单产品和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_idproduct_id,分别为外键表ordersproducts

您的订单类将是:

@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一起使用,这将不起作用。

如果您确实需要的是多对多的表格,则提供的代码将对您有所帮助。

+0

您好,感谢您的评论。那么这就是我原来的代码,但是我需要在函数表中有额外的字段,所以一个简单的ManyToMany关联将不起作用 - OrderLine将有大约6个与它相关的属性,'product_size','product_color',等现在有意义吗?还有,@Id的多次使用是特意完成的,我构建的教程是在构造从其他实体主键派生的组合键时执行的。谢谢 – 2014-11-25 18:10:37

我得到了它在我的最后一次尝试,昨晚做这个变化

在订单行

我删除了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 

我不认为这个工作正常,但正确的表格正确值已更新,这是否有效?

谢谢