2014-11-25 52 views
0

好吧,所以今天我花了一整天的時間試圖找出如何映射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; 
} 

終點可以請別人幫我,這是推動我瘋了....

謝謝

回答

0

好吧,我想通了 - 我結束了使用嵌入的方法,而不是基於這個傢伙的優秀教程^ h ere

他經歷來實現多對多assosiations 3個主要途徑 - 一個簡單的只有聯合表的表,一個聯結表(帶有附加字段),這是我需要實現的方法,最後是一個不太流行的方法,其中類被映射爲組件。

0

經過你的問題和代碼後,我認爲你的設計錯了。

你說

想要的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

0

我得到了它在我的最後一次嘗試,昨晚做這個變化

在訂單行

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

我不認爲這個工作正常,但正確的表格正確值已更新,這是否有效?

謝謝