当前位置: 首页 > 知识库问答 >
问题:

Orders Products和Order\u Line与复合键的Hibernate关系

益麻雀
2023-03-14

好吧,今天我花了一整天试图弄清楚如何使用hibernate使用注释all java config映射Orders、Products和OrderLine之间的关系。

我希望OrderLine是一个带有额外字段的连接表,用于连接产品和订单。

订单与订单线有一对多的关系-一个订单有许多订单线。

每个订单有一个或多个订单行,每个订单行有一个订单,每个订单行有一个产品,每个产品可以有0个或多个订单行。

从我一直遵循的教程来看,有两种方法可以做到这一点。一个是@Embedded、@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;
}

谁能帮帮我,这让我发疯了。。。。

非常感谢。

共有3个答案

施驰
2023-03-14

好吧,我想通了——我最终使用了可嵌入的方法,而不是基于这个家伙的优秀教程

他通过3种主要方法来实现多对多的assosiations-一个简单的仅连接表,一个连接表(带有附加字段),这是我需要实现的方法,最后是一个不太流行的方法,其中类被映射为一个组件

金坚
2023-03-14

我昨晚最后一次尝试的时候做了这个改变

在OrderLine中,我删除了product\u id和order\u id字段,并将@id注释放置在两个manytone关系上,如下所示

@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

我不认为这会起作用,但更新了具有正确值的正确表,这有效吗?

非常感谢。

胡景澄
2023-03-14

看完你的问题和代码后,我认为你的设计错了。

你说

希望OrderLine是一个带有额外字段的连接表,用于连接产品和订单。

但是,您的OrderLine类中只有两个变量,订单和产品。

如果我没说错的话,你真正需要的是一张多对多的桌子。

您的表的订单行将包含两列,分别是表订单和产品的外键。

您的订单类别为:

@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指定给Set,并且将@Id与@OneToMany一起使用,这将不起作用。

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

 类似资料:
  • 我正在努力解决hibernate映射问题,即在订单表的主键和带有一些额外列的产品购物车的复合键之间映射一对多关系 产品购物车表具有组合键购物车ID和产品ID 我试着跟踪但没有成功 有人能帮我实现这一点吗?下面是错误消息 原因:组织。冬眠AnnotationException:非法尝试使用mappedBy关联pcoPK定义@JoinColumn。组织pk。冬眠cfg公司。Ejb3JoinColumn

  • 我在使用复合主键的hibernate实体集时遇到了问题。 我们的应用程序中有一个概念“Target”。目标id应该是其他三个表(实体)主id的组合。目标也有一个int标记。员工应该有一系列目标。SQL如下所示: 这个SQL工作正常,它允许我每个role_id(员工)多个目标,只要应用程序和项目分类不同。 这是目标ID类 这是目标类 这是employee类,我想在其中为每个员工存储一组目标。 通过h

  • 我正在使用JPA(Hibernate)并试图用childs和复合键持久化整个新实体,但当持久化childs时,我在键中得到了null。表结构: 映射:

  • 我有一些实体: 当我试图保存新的cbonus记录时,出现异常: org.postgresql.util.PSQLException: ERROR: null值在列"bank_id"的关系"cBonus"违反了非空约束详细信息:失败的行包含(773, gp3, null, null, f)。 和查询 DEBUG 24817-[nio-8080-exec-4]org . hibernate . SQL

  • 它应该允许独立地更新表,并在父行被删除时删除子行。

  • 我用复合键定义了两个实体之间的多对多关系。问题是,当我获得join对象时,它只被过滤了关系的一侧,而不是两边。 图片使问题更加清晰。这里,我要查找的是dtid=185和prid=352,但我从多对多关系中得到的是两个突出显示的行。 天丁: