了解具有多个项目引用的Hibernate级联行为

时间:2015-08-13 11:55:02

标签: java hibernate jpa cascade

我不了解某个应该由Cascade.ALL设置保留的对象的Hibernate行为,但在同一事务中的另一个引用中被视为未保存。

示例:

OrderProposal proposal = new OrderProposal();
ProposalLineItem proposalLine = new ProposalLineItem();
proposalLine.setProposal(proposal);
proposal.addLineItem(proposalLine); //to be saved by cascade.all via proposal
saveOrUpdate(proposal);

Order order = new Order();
OrderLineItem orderLine = new OrderLineItem(); //to be saved by cascade.all via order
orderLine.setProposalLine(proposalLine); //proposalLine is not mapped as cascaded from orderLine
proposalLine.setOrderLine(orderLine);
order.addLineItem(orderLine);
saveOrUpdate(order); 

如果在单个事务中运行,则Hibernate在处理订单对象的级联时抛出:

org.hibernate.TransientPropertyValueException: object references an 
unsaved transient instance - save the transient instance before flushing : orderLine.proposalLine

我是否必须明确保存proposalLine才能使其正常工作?

EDITED

以下是受影响的hibernate映射:

@Entity
@Access(AccessType.FIELD)
@Proxy(lazy = false)
@OptimisticLocking(type = OptimisticLockType.VERSION)
public class ProposalLineItem {

    @ManyToOne(optional = false)
    @JoinColumn(name = "proposal_id")
    private OrderProposal proposal;


    @OneToOne(mappedBy = "proposalLine")
    @NotFound(action = NotFoundAction.EXCEPTION)
    private OrderLineItem orderLine;
}


@Entity
@OptimisticLocking(type = OptimisticLockType.VERSION)
@Proxy(lazy = false)
@Access(AccessType.FIELD)
public class OrderProposal {

    @OneToMany(mappedBy = "proposal", orphanRemoval = true, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @OrderColumn(name = "listIndex", nullable = false)
    private List<ProposalLineItem> lineItems;

}



@Entity
@Proxy(lazy = false)
@OptimisticLocking(type = OptimisticLockType.VERSION)
@Access(AccessType.FIELD)
public class OrderLineItem {

    @OneToOne(optional = false)
    @NotFound(action = NotFoundAction.EXCEPTION)
    @JoinColumn(name = "proposal_line_id", nullable = false)
    private ProposalLineItem proposalLine;

}



@Entity
@OptimisticLocking(type = OptimisticLockType.VERSION)
@Proxy(lazy = false)
@Access(AccessType.FIELD)
public class Order {

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    @JoinColumn(name = "order_id")
    @IndexColumn(nullable = false, name = "listIndex", base = 0)
    private List<OrderLineItem> lineItems;

}

1 个答案:

答案 0 :(得分:-1)

  

Cascade是一种方便的功能,可以保存所需的代码行   手动管理另一方的状态。

所以说让我们假设你有一个对象依赖于另一个对象而你想删除它将如何删除它?如果不存在级联,则必须手动触发其他查询后的1。因此,在hibernate中,如果要定义对象之间的关系,则必须使用级联属性,因此通过定义它,如果对Parent类对象进行任何更改,子类对象也会生效。

现在您已经提到cascade = “all”您告诉级联将申请insert/update/delete

级联可以适用save/update/delete等。

现在,如果cascade = “none”,那么只会影响父类对象,而不会影响子类。