尽管有一个复合主键,但是当只有一个键是唯一的时,Hibernate会给出一个错误 [英] Although there is a Composite Primary Key, Hibernate gives an error when only one key is unique

查看:74
本文介绍了尽管有一个复合主键,但是当只有一个键是唯一的时,Hibernate会给出一个错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个Hibernate错误,该错误提示找到了多个具有给定标识符的行,而我一直坚持下去. 我真的很感谢任何帮助.

I'm facing an Hibernate error which says More than one row with the given identifier was found and I'm stuck with it. I would really appreciate any help on this.

  • 我想创建一个表作为 orderLine 作为表,其中包含特定销售订单的产品代码,数量等.
  • 一个 SalesOrder 可以包含许多orderLine.

  • I want to create a table as orderLine that contains product code, quantity .etc for a particular sales order.
  • A SalesOrder can contain many orderLines.

orderLine表的组合键为 productCode + OrderNumber . ProductCode是 Product 表的主键,而OrderNumber是 SalesOrder 表的主键.

The composite key for the orderLine table is productCode + OrderNumber. ProductCode is the primary key of the Product table and OrderNumber is the primary key of the SalesOrder table.

复合键正在正确生成,并且我收到了hibernate记录的以下sql语句.

The composite key is getting generated correctly and I get the following sql statement logged by hibernate.

休眠:创建表orderLine(orderNumber varchar(255)不为null,productCode varchar(255)不为null,status varchar(255)不为null,数量整数不为null,totalPrice双精度不为null,unitPrice双精度不为null,主键(orderNumber,productCode))

Hibernate: create table orderLine (orderNumber varchar(255) not null, productCode varchar(255) not null, status varchar(255) not null, quantity integer not null, totalPrice double precision not null, unitPrice double precision not null, primary key (orderNumber, productCode))

当OrderLine表包含以下数据时,我已成功使用 OrderNumber ORD001& 产品代码 BIS1003

When the OrderLine table contains data as below, I Successfully insert a new record to OrderLine table with the OrderNumber ORD001 & ProductCode BIS1003

  • 当我尝试从OrderLine中获取记录后,立即出现以下错误.

  • Immediately after when I try to fetch records from the OrderLine, I'm getting the following error.

原因:org.hibernate.HibernateException:找到了多个具有给定标识符的行:BIS1003,针对类:com.salesOrder_ws.entity.OrderLine

由于有一个复合键作为主键,为什么当复合键中只有一个键不是唯一键时,hibernate会引发异常?

Since there is a composite key as the primary, why is hibernate throwing an exception, when only one key of the composite key is not unique?

代码在下面.

OrderLine实体:

OrderLine Entity:

  @Entity
    @Table(name = "orderLine")
    public class OrderLine implements Serializable{

    private static final long serialVersionUID = -851110991599534263L;


    @AttributeOverrides(value = 
            {@AttributeOverride(column = @Column(name="productCode"), name = "productCode"),
            @AttributeOverride(column = @Column(name="orderNumber"), name = "orderNumber")})
    @EmbeddedId
    private LineID pk;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "productCode", insertable = false, updatable = false)
    private Product product;

    private int quantity;

    private double unitPrice;

    private double totalPrice;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "orderNumber", nullable=false, insertable=false, updatable=false)
    private SalesOrder salesOrder;


    @Override
    public boolean equals(Object obj) {

        try {
            LineID line = (LineID) obj;
            return (this.getSalesOrder().getOrderNumber()
                    .equals(line.getOrderNumber()) && this.getProduct()
                    .getCode().equals(line.getProductCode()));
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return (this.getProduct().getCode() + "" + this.getProduct().getCode()).hashCode();
    }
}

SalesOrder实体

SalesOrder Entity

@Entity
@Table(name = "salesOrder")
public class SalesOrder extends BaseEntity{

    @Id
    private String orderNumber;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "customerCode", nullable = false)
    private Customer customer;

    private double totalPrice;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "salesOrder", cascade = CascadeType.ALL)
    private List<OrderLine> lines;


    @Override
    public boolean equals(Object obj) {

        try {
            SalesOrder so = (SalesOrder) obj;
            if (this.getOrderNumber().equals(so.getOrderNumber())) {
                return true;
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return this.getOrderNumber().hashCode();
    }
}

可嵌入类

@Embeddable
public class LineID implements Serializable{

    private static final long serialVersionUID = -4478828739881744452L;
    @Basic(optional = false)
    private String productCode;
    @Basic(optional = false)
    private String orderNumber;

    @Override
    public boolean equals(Object obj) {
        try {
            LineID l = (LineID) obj;
            return this.productCode.equals(l.getProductCode()) && this.orderNumber.equals(l.getOrderNumber());
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return (this.getOrderNumber() + "" + this.getProductCode()).hashCode();
    }
}

更新

Hibernate生成的SQL:

SQL generated by Hibernate :

Hibernate: create table customer (code varchar(255) not null, status varchar(255) not null, address varchar(255), creditLimit double precision not null, currentCredit double precision not null, name varchar(255), phone1 varchar(255), phone2 varchar(255), primary key (code))
Hibernate: create table orderLine (orderNumber varchar(255), productCode varchar(255), status varchar(255) not null, quantity integer not null, totalPrice double precision not null, unitPrice double precision not null, primary key (orderNumber, productCode))
Hibernate: create table product (code varchar(255) not null, status varchar(255) not null, description varchar(255), price double precision not null, quantity integer not null, primary key (code))
Hibernate: create table salesOrder (orderNumber varchar(255) not null, status varchar(255) not null, totalPrice double precision not null, customerCode varchar(255) not null, primary key (orderNumber))
Hibernate: alter table orderLine add constraint UK_9gf3j9l0n1w7d2h4sso3voc77 unique (productCode)
Hibernate: alter table orderLine add index FK_9gf3j9l0n1w7d2h4sso3voc77 (productCode), add constraint FK_9gf3j9l0n1w7d2h4sso3voc77 foreign key (productCode) references product (code)
Hibernate: alter table orderLine add index FK_ojvge4lucwf2gtihxtmnav3u2 (orderNumber), add constraint FK_ojvge4lucwf2gtihxtmnav3u2 foreign key (orderNumber) references salesOrder (orderNumber)
Hibernate: alter table salesOrder add index FK_4lq8ynumala22y9t17ceawo81 (customerCode), add constraint FK_4lq8ynumala22y9t17ceawo81 foreign key (customerCode) references customer (code)

休眠:更改表orderLine添加约束UK_9gf3j9l0n1w7d2h4sso3voc77唯一(productCode)

上面的SQL不是要生成的.如果我能避免这种独特的约束,那么问题将得到解决.

The above SQL is not intended to generate. If I could avoid this unique constraint, the problem will be solved.

感谢您提供帮助以解决此问题.

Appreciate any help to resolve this issue.

推荐答案

我认为您可能缺少

I think you might be missing the @MapsId annotation:

@Entity
@Table(name = "orderLine")
public class OrderLine implements Serializable{

    private static final long serialVersionUID = -851110991599534263L;

    @AttributeOverrides(value = 
            {@AttributeOverride(column = @Column(name="productCode"), name = "productCode"),
            @AttributeOverride(column = @Column(name="orderNumber"), name = "orderNumber")})
    @EmbeddedId
    private LineID pk;

    @ManyToOne(cascade = CascadeType.ALL)
    @MapsId("productCode")
    private Product product;

    private int quantity;

    private double unitPrice;

    private double totalPrice;

    @ManyToOne(fetch = FetchType.EAGER)
    @MapsId("orderNumber")
    private SalesOrder salesOrder;


    @Override
    public boolean equals(Object obj) {

        try {
            LineID line = (LineID) obj;
            return (this.getSalesOrder().getOrderNumber()
                    .equals(line.getOrderNumber()) && this.getProduct()
                    .getCode().equals(line.getProductCode()));
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return (this.getProduct().getCode() + "" + this.getProduct().getCode()).hashCode();
    }
}

这篇关于尽管有一个复合主键,但是当只有一个键是唯一的时,Hibernate会给出一个错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆