好的,今天我花了一整天时间试图找出如何使用注释全部java配置来映射Orders,Products和OrderLine之间的关系和hibernate。
我希望OrderLine成为一个包含额外字段的联结表,它连接产品和订单。
订单与OrderLine有一个OneToMany关系 - 一个订单有很多订单行。
每个订单都有一个或多个OrderLines,每个OrderLine有一个订单,每个OrderLine有一个产品,每个产品可以有0个或更多OrderLines。
从我一直关注的教程中,有两种方法可以做到。一个是@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
}
这是我的OrderLine类
@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 :(得分:0)
在完成您的问题和代码后,我认为您的设计有误。
你说
希望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
}
正如您所看到的,从订单实体中您可以获得产品&#39;从产品实体中,您可以获得订单&#39;。这应该服务于你的目的。无需使用&#39; OrderLine&#39;类。
代码中的其他主要错误: - @Id用于表示主键。您已经多次使用@Id进行单一课程。 - 在&#39;订单&#39; class @Id给了Set,而@Id和@OneToMany一起使用,后者无法工作。
如果您需要的是多对多表,那么提供的代码可以帮助您。
答案 1 :(得分:0)
我做了这个改变,昨晚做了最后一次尝试
在OrderLine中我删除了product_id和order_id字段,并将@Id注释放在ManyToOne关系上,如此
@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
我认为这个woudl不起作用,但更新了正确值的正确表格,这是否有效?
谢谢
答案 2 :(得分:0)
好的,我想通了 - 我最终使用了embeddable方法而不是基于这个优秀的教程h ere
他通过3种主要方式来实现多对多的关联 - 一个简单的只有联结表,一个联结表(带有附加字段),这是我需要实现的方法,最后是一个不太流行的方法,其中类被映射作为一个组成部分。