无法在hibernate中更新一对一关系的对象

时间:2013-09-07 17:36:13

标签: sql spring hibernate

我有如下所示的关系:

    @Entity
@Table(name = "ORDER_", catalog = "smartorder")
public class Order implements Serializable {

    /**
     * serial version id
     */
    private static final long serialVersionUID = 13875615L;

    @Id
    @Column(name = "ORDER_ID", unique = true, nullable = false)
    @SequenceGenerator(name = "ORDER_ID_GEN", sequenceName = "ORDER_ID_SEQ")
    @GeneratedValue(generator = "ORDER_ID_GEN")
    private long orderId;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "INVOICE_ID", referencedColumnName = "INVOICE_ID")
    private Invoice invoice;

    // setters and getters
}





@Entity
@Table(name = "INVOICE_")
public class Invoice implements Serializable {
    /**
     * serial version id
     */
    private static final long serialVersionUID = 13875612L;

    @Id
    @Column(name = "INVOICE_ID", unique = true, nullable = false)
    @SequenceGenerator(name = "INVOICE_ID_GEN", sequenceName = "INVOICE_ID_SEQ")
    @GeneratedValue(generator = "INVOICE_ID_GEN")
    private int invoiceId;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "ORDER_ID", referencedColumnName = "ORDER_ID")
    private Order order;

    @Column(name = "SUB_TOTAL", precision = 6, nullable = false)
    private double subTotal;

    @Column(name = "SERVICE_TAX", precision = 6, nullable = false)
    private double serviceTax;

    @Column(name = "VAT", precision = 6, nullable = false)
    private double vat;

    @Column(name = "SURCHAARGE", precision = 6, nullable = false)
    private double surChaarge;

    @Column(name = "GRAND_TOTAL", precision = 6, nullable = false)
    private double grandTotal;


    //setters and getters
}

我能够正确保存记录。但是当我试图通过将发票对象设置为订单对象来更新订单对象时,订单对象也是持久的,只有发票对象是持久的。

Order o = getSession().load(Order.class,1L);
o.setInvoice(new Invoice(.........));
getSession().update(o);
在控制台中

我只能看到一个SQL语句, 插入INVOICE_(DISCOUNT,GRAND_TOTAL,ORDER_ID,ROUNDING,SERVICE_TAX,SUB_TOTAL,SURCHAARGE,VAT)值(?,?,?,?,?,?,?,?)

发票ID未在订单表中获得更新:(

任何人都可以提出问题是什么。

提前致谢.....

2 个答案:

答案 0 :(得分:2)

这可能取决于您的不寻常设计。

使用ORDR_中的INVOICE_ID和INVOICE_中的ORDER_ID,您可以同时拥有彼此父级和子级的两个表。

如果您的数据库使用外键删除和插入将很难。

你应该使用一个类型/表作为父类,(例如,Order,因为它首先是normaly),另一个作为child(order_id将在invoice_表中)。

在对象模型中,您可以同时拥有两个方向(请参阅http://docs.oracle.com/javaee/6/api/javax/persistence/OneToOne.html的第一个示例)

答案 1 :(得分:1)

问题是您使用实体/表格和一对一映射样式的错误方案。 一对一的概念与您当前设计的表和实体都不相符。

请尝试在此处详细了解一对一:The concept for one-to-one mapping. Explain the mapping

大多数情况下请仔细查看:Hibernate – One-to-One example (Annotation),您可以在其中找到一对一映射的示例。

如果你真的想继续进行一对一的映射,你必须:

  1. 从“INVOICE_”表中删除“INVOICE_ID”列(令人惊讶但事实真相)
  2. 将“INVOICE_”表中的“ORDER_ID”列作为主键(另一个事实)
  3. 将Invoice实体的映射更改为更顺从(由Order实体驱动)
  4. 发票映射更改示例:

    // just a draft, to give you idea about the 
    // "submissive" side mapping.
    // All the ID stuff of the Invoice is driven by its 
    // "Master" - Order
    @GenericGenerator(name = "generator", strategy = "foreign", 
    parameters = @Parameter(name = "property", value = "order"))
    @Id
    @GeneratedValue(generator = "generator")
    @Column(name = "ORDER_ID", unique = true, nullable = false)
    public Integer getOrderId() {
        return this.orderId;
    }
    
    public void setOrderId(Integer orderId) {
        this.orderId = orderId;
    }
    
    @OneToOne(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn
    public Order getOrder() {
        return this.order;
    }
    

    请将其作为草稿,以显示一对一概念的不同之处。