休眠外键问题

时间:2019-03-22 09:11:25

标签: java hibernate jpa orm hibernate-mapping

我想通过休眠设计与组成键的多对多关系。 除book外,我使用了3个类,包括ordersorderDetailcomposition key class类。在数据库中,有3个表分别以BOOKORDERSORDER_DETAIL命名。

我在hibernate.cfg.xml中定义了所有映射类。

<mapping class="com.bookstore.entity.Book"/>
<mapping class="com.bookstore.entity.OrderDetail"/>
<mapping class="com.bookstore.entity.OrderDetailId"/>
<mapping class="com.bookstore.entity.Orders"/>   

    <!-- Drop and re-create the database schema on start-up -->
    <property name="hibernate.hbm2ddl.auto">update</property>

下面是我的课程。

图书课

@Entity
@Table(name="BOOK",catalog = "JSPPROJECTDATABASE")
public class Book implements Serializable{

    @Id
    @SequenceGenerator(name="BOOK_SEQ", sequenceName="BOOK_SEQ", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="BOOK_SEQ")
    @Column(name="BOOK_ID", nullable = false)
    private int id;

    @OneToMany(mappedBy = "pk.books", cascade=CascadeType.ALL)
    private Set<OrderDetail> orderDetails = new HashSet<OrderDetail>();

    // constructor

    // getter and setter 

    public Set<OrderDetail> getOrderDetails() {
        return orderDetails;
    }

    public void setOrderDetails(Set<OrderDetail> orderDetails) {
        this.orderDetails = orderDetails;
    }

}

对于订单类

@Entity
@Table(name="ORDERS",catalog = "JSPPROJECTDATABASE")
public class Orders implements Serializable{

    @Id
    @SequenceGenerator(name="ORDERS_SEQ", sequenceName="ORDERS_SEQ", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ORDERS_SEQ")
    @Column(name="ORDER_ID", nullable = false)
    private int id;

    @OneToMany(mappedBy = "pk.order", cascade=CascadeType.ALL)
    private Set<OrderDetail> orderDetails = new HashSet<OrderDetail>();

    // constructor

    // getter and setter

    public Set<OrderDetail> getOrderDetails() {
        return orderDetails;
    }

    public void setOrderDetails(Set<OrderDetail> orderDetails) {
        this.orderDetails = orderDetails;
    }

}

OrderDetail类

@Entity
@Table(name = "ORDER_DETAIL", catalog = "JSPPROJECTDATABASE")
@AssociationOverrides({
        @AssociationOverride(name = "pk.order", 
            joinColumns = @JoinColumn(name = "ORDER_ID")),
        @AssociationOverride(name = "pk.books", 
            joinColumns = @JoinColumn(name = "BOOK_ID")) })
public class OrderDetail implements Serializable{

    private OrderDetailId pk = new OrderDetailId();

    @Column(name="QUANTITY")
    private int quantity;

    @Column(name="SUBTOTAL")
    private float subTotal;

    public OrderDetail() {
        super();
        // TODO Auto-generated constructor stub
    }

    @EmbeddedId
    public OrderDetailId getPk() {
        return pk;
    }

    public void setPk(OrderDetailId pk) {
        this.pk = pk;
    }

    @Transient
    public Book getBook() {
        return getPk().getBooks();
    }

    public void setBook(Book book) {
        getPk().setBooks(book);
    }

    @Transient
    public Orders getOrders() {
        return getPk().getOrder();
    }

    public void setOrders(Orders orders) {
        getPk().setOrder(orders);
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public float getSubTotal() {
        return subTotal;
    }

    public void setSubTotal(float subTotal) {
        this.subTotal = subTotal;
    }

}

以OrderDetailId命名的复合类

@Embeddable
public class OrderDetailId implements Serializable{

    @ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "BOOK_ID",insertable = false, updatable = false,nullable = false)
    private Book books;

    @ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "ORDER_ID",insertable = false, updatable = false,nullable = false)
    private Orders order;

    public Book getBooks() {
        return books;
    }
    public void setBooks(Book books) {
        this.books = books;
    }
    public Orders getOrder() {
        return order;
    }
    public void setOrder(Orders order) {
        this.order = order;
    }

}

运行代码时,屏幕上出现错误。

    org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table REVIEW add constraint FKf8kovbt4otqcvp75w008agrbx foreign key (CUSTOMER_ID) references CUSTOMER" via JDBC Statement
    at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67)

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table REVIEW add constraint FKf339wkg63wmuutk10j4iowly0 foreign key (BOOK_ID) references BOOK" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table ORDERS add constraint FKkdbly1ij6f4kqh378kfne6ilx foreign key (CUSTOMER_ID) references CUSTOMER" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table ORDER_DETAIL add constraint FKag30vapylo13u3lax0elv3n06 foreign key (order) references ORDERS" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table ORDER_DETAIL add constraint FKqk2p0pl26ysleeejh8isy44or foreign key (books) references BOOK" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table BOOK add constraint FKprh5cdnlwefrxo30ausnijl3d foreign key (CATEGORY_ID) references CATEGORY" via JDBC Statement

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "alter table ORDER_DETAIL add order raw(255) not null" via JDBC Statement

如果我在类中定义了任何错误的变量,或者在其关系中定义了任何错误的关联,该如何解决?

2 个答案:

答案 0 :(得分:1)

这是因为mappedBy用于表示一个字段,该字段用于映射(该字段的名称)。您可能使用了列名。如果要使用mappedBy,则需要声明双向关系,在子方面使用@JoinColumn。然后,您可以将该字段的名称传递到mappedBy中。

假设您在OrderDetailId中具有以下内容:

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "BOOK_ID")
private Book books;

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name = "ORDER_ID")
private Orders order;

然后在Orders中输入

@OneToMany(mappedBy = "order", cascade=CascadeType.ALL)
private Set<OrderDetail> orderDetails = new HashSet<OrderDetail>();

Book中的

@OneToMany(mappedBy = "pk.books", cascade=CascadeType.ALL)
private Set<OrderDetail> orderDetails = new HashSet<OrderDetail>();

答案 1 :(得分:1)

您必须使用列进行映射。

但是在您为OrderDetailId编写的代码中,您使用了另一个实体引用。

为了获得更好的设计,您必须在ID class

中使用简单的ID