Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 虽然有一个复合主键,但当只有一个键是唯一的时,Hibernate会给出一个错误_Java_Hibernate_Jpa_Hibernate Mapping_Composite Primary Key - Fatal编程技术网

Java 虽然有一个复合主键,但当只有一个键是唯一的时,Hibernate会给出一个错误

Java 虽然有一个复合主键,但当只有一个键是唯一的时,Hibernate会给出一个错误,java,hibernate,jpa,hibernate-mapping,composite-primary-key,Java,Hibernate,Jpa,Hibernate Mapping,Composite Primary Key,我正面临一个Hibernate错误,该错误表示找到了多个具有给定标识符的行,我被困在其中。 我真的很感激在这方面的任何帮助 我想创建一个表作为订单行,其中包含特定销售订单的产品代码、数量等 销售订单可以包含许多订单行 orderLine表的复合键是productCode+OrderNumber。ProductCode是Product表的主键,OrderNumber是SalesOrder表的主键 在单个SalesOrder中,特定产品应该只有一个订单行 复合键生成正确,我得到了hibernate

我正面临一个Hibernate错误,该错误表示找到了多个具有给定标识符的行,我被困在其中。 我真的很感激在这方面的任何帮助

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

  • orderLine表的复合键是productCode+OrderNumber。ProductCode是Product表的主键,OrderNumber是SalesOrder表的主键

  • 在单个SalesOrder中,特定产品应该只有一个订单行
  • 复合键生成正确,我得到了hibernate记录的以下sql语句

    Hibernate:创建表医嘱行(医嘱号varchar(255)不为空,产品代码varchar(255)不为空,状态varchar(255)不为空,数量整数不为空,总价双精度不为空,单价双精度不为空,主键(医嘱号,产品代码))

  • 当OrderLine表包含如下数据时,我成功地向OrderLine表插入了一条新记录,其中包含OrderNumberORD001&ProductCodeBIS1003

  • 当我尝试从订单行获取记录后,立即出现以下错误

    原因:org.hibernate.HibernateException:找到多个具有给定标识符的行:BIS1003,用于类:com.salesOrder\u ws.entity.OrderLine

  • 既然有一个复合密钥作为主密钥,为什么hibernate会在复合密钥中只有一个密钥不是唯一的情况下抛出异常

代码如下

订单行实体:

  @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();
    }
}
销售订单实体

@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();
    }
}
更新

由Hibernate生成的SQL:

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)
Hibernate:alter table orderLine add constraint UK_9gf3j9l0n1w7d2h4sso3voc77 unique(产品代码)

上述SQL不打算生成。如果我能避免这个独特的限制,问题就会解决


感谢您为解决此问题提供的帮助。

我认为您可能缺少注释:

@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();
    }
}

重写主程序中的equals和hashCode方法key@Simo:我得到了相同的错误:(原因:org.hibernate.HibernateException:找到多个具有给定标识符的行:BIS1003,用于类:com.salesOrder_ws.entity)。OrderLine@Simo:我用为可嵌入类添加的hash code&equals方法更新了问题。好的,再试一次。您可以从订单行实体中删除equals和hashcode吗se在您的LineID中使用了从eclipse生成的equals和hashcode方法……只是一个尝试。我认为问题的出现就是因为这个methods@Simo:相同的结果:(无论如何,非常感谢您的想法。感谢您的快速回答。不幸的是,它没有起作用。我可以看到一个我不想具有的唯一约束。
Hibernate:alter table orderLine add constraint UK_9gf3j9l0n1w7d2h4sso3voc77 unique(productCode)
如果我可以避免创建此约束,问题将得到解决。我已使用生成的SQL语句更新了问题。您需要将
@OneToOne
产品关联更改为
@ManyToOne
。检查我更新的答案。
@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();
    }
}