Jpa + Spring Data:使用复合键级联集合

时间:2015-01-14 02:19:14

标签: java spring hibernate jpa spring-data

我目前正在为我的学校开设小型商店申请。

我想要保存2个对象:

Order.java

@Entity
@Table(name = "ORDERS")
public class Order {
    private Integer id;
    private Date orderDate;
    private MailingAddress mailingAddress;
    private User user;
    private Collection<OrderLine> orderLines;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Basic
    @Column(name = "ORDER_DATE")
    public Date getOrderDate() {
        return orderDate;
    }

    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }

    @ManyToOne
    @JoinColumn(name = "SHIPPING_ADR_ID", referencedColumnName = "ID")
    public MailingAddress getMailingAddress() {
        return mailingAddress;
    }

    public void setMailingAddress(MailingAddress mailingAddressByShippingAdrId) {
        this.mailingAddress = mailingAddressByShippingAdrId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "USER_ID", referencedColumnName = "LOGIN")
    public User getUser() {
        return user;
    }

    public void setUser(User userByUserId) {
        this.user = userByUserId;
    }

    @OneToMany(mappedBy = "order", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    public Collection<OrderLine> getOrderLines() {
        return orderLines;
    }

    public void setOrderLines(Collection<OrderLine> orderLinesesById) {
        this.orderLines = orderLinesesById;
    }
}

OrderLine.java

@Entity
@Table(name = "ORDER_LINES", schema = "")
@IdClass(OrderLinesPK.class)
public class OrderLine {
    private int quantity;
    private Integer orderId;
    private String bookId;
    private Book book;
    private Order order;

    @Basic
    @Column(name = "QUANTITY")
    public int getQuantity() {
        return quantity;
    }

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

    @Id
    @Column(name = "ORDERS_ID", insertable = false, updatable = false)
    public Integer getOrderId() {
        return orderId;
    }

    public void setOrderId(Integer ordersId) {
        this.orderId = ordersId;
    }

    @Id
    @Column(name = "BOOKS_ID", insertable = false, updatable = false)
    public String getBookId() {
        return bookId;
    }

    public void setBookId(String booksId) {
        this.bookId = booksId;
    }

    @ManyToOne
    @JoinColumn(name = "BOOKS_ID", referencedColumnName = "ISBN13", nullable = false, insertable = false, updatable = false)
    public Book getBook() {
        return book;
    }

    public void setBook(Book booksByBookId) {
        this.book = booksByBookId;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ORDERS_ID", referencedColumnName = "ID", nullable = false, insertable = false, updatable = false)
    public Order getOrder() {
        return order;
    }

    public void setOrder(Order ordersByOrderId) {
        this.order = ordersByOrderId;
    }
}

OrderLinesPK.java

public class OrderLinesPK implements Serializable {
    private int ordersId;
    private String booksId;

    @Column(name = "ORDERS_ID")
    @Id
    public int getOrderId() {
        return ordersId;
    }

    public void setOrderId(int ordersId) {
        this.ordersId = ordersId;
    }

    @Column(name = "BOOKS_ID")
    @Id
    public String getBookId() {
        return booksId;
    }

    public void setBookId(String booksId) {
        this.booksId = booksId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        OrderLinesPK that = (OrderLinesPK) o;

        if (ordersId != that.ordersId) return false;
        if (booksId != null ? !booksId.equals(that.booksId) : that.booksId != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = ordersId;
        result = 31 * result + (booksId != null ? booksId.hashCode() : 0);
        return result;
    }
}

订单包含订单行的集合。 我试图在一次调用OrderRepository时保存订单+订单行。 但是当我这样做时,我得到了错误

org.hibernate.PropertyAccessException: Null value was assigned to a property of primitive type setter of edu.flst.bookstore.domaine.bo.OrderLinesPK.orderId

这是非常逻辑的(我知道订单的Id在这个阶段是未知的,因为订单的主键是自动递增的(我使用MySQL))。

我不知道如何通过一次调用来使用orderService(不首先使用orderLinesRepository保存orderLines)。它甚至可能吗?

此致

1 个答案:

答案 0 :(得分:0)

订单可以包含许多书籍,书籍可以出现在许多订单中。因此,多对多关系本质上是您的OrderLine对象。我会在OrderLine中设置一个id(自动生成)和两个多对一关系。然后丢弃OrderLinesPK类,在同一事务中按顺序保存Order,Book和OrderLine对象。这样,您的模型更简单,您只需要在数据库中保存额外的id(没有物理意义) (OrderLine对象的id)