jpa+hibernate一对多双向关联关系更新问题

时间:2022-11-26 20:43:28
就好比订单(Order)和订单项(OrderItem)
订单一的一方,订单项是多的一方
原本订单A里面有四个订单项(1,2,3,4)
现在有一个订单项不要了(4),最终只保留(1,2,3)
费了半天劲也没有保存成功为什么
请大牛指点*

9 个解决方案

#1


该回复于2012-03-13 14:49:38被版主删除

#2


这个问题没有叙述清楚,建议楼主重新整理下问题,大家好来跟帖,呵呵呵。

#3


该回复于2012-03-13 14:54:53被版主删除

#4


该回复于2012-03-13 14:54:53被版主删除

#5


嗯,我再来详细描述

有一订单类 Order

public class Order{
 private String ID;
 private Set OrderItems = new HashSet();

/*添加订单项的方法*/
addOrderItem(OrderItem orderItem){
OrderItems.add(orderItem);
}

/*移除订单项的方法*/
removeOrderItem(OrderItem orderItem){
OrderItems.remove(orderItem);
orderItem.setOrder(null);
}

 getXX();setXX();
......
}
还有个订单项
public class OrderItem{
 private String ID;
 private Order order;

public OrderItem(String ID){
 this.ID = ID;
}

 getXX();setXX();
...............
}

订单Order和订单项的关联关系是一对多
一个订单多个订单项,并且订单项里面的订单字段必须存在(就好比是一夫多妻制一样,妻子肯定要有丈夫)


接下来做一保存
Order order = new Order();
order.addOrderItem(new OrderItem("1"));
order.addOrderItem(new OrderItem("4"));
order.addOrderItem(new OrderItem("3"));
order.addOrderItem(new OrderItem("2"));

orderService.persist(Order);

则这个order中有四个小项ID分别为1,2,3,4
现在这个order有想法了,不想要ID为“1”的小项了(就好像你有了四个老婆,大老婆太老了,难看了不要了)接下来就进行操作

order.removeOrderItem(new OrderItem("1"));
orderService.merge(order);

理论上应该可以的但是实际上更新之后还是有四个订单小项(大老婆没有解除掉,这怎么能再娶下一个呢)
大牛们看看呗

#6


嗯,我再来详细描述

有一订单类 Order

public class Order{
 private String ID;
 private Set OrderItems = new HashSet();

/*添加订单项的方法*/
addOrderItem(OrderItem orderItem){
OrderItems.add(orderItem);
}

/*移除订单项的方法*/
removeOrderItem(OrderItem orderItem){
OrderItems.remove(orderItem);
orderItem.setOrder(null);
}

 getXX();setXX();
......
}
还有个订单项
public class OrderItem{
 private String ID;
 private Order order;

public OrderItem(String ID){
 this.ID = ID;
}

 getXX();setXX();
...............
}

订单Order和订单项的关联关系是一对多
一个订单多个订单项,并且订单项里面的订单字段必须存在(就好比是一夫多妻制一样,妻子肯定要有丈夫)


接下来做一保存
Order order = new Order();
order.addOrderItem(new OrderItem("1"));
order.addOrderItem(new OrderItem("4"));
order.addOrderItem(new OrderItem("3"));
order.addOrderItem(new OrderItem("2"));

orderService.persist(Order);

则这个order中有四个小项ID分别为1,2,3,4
现在这个order有想法了,不想要ID为“1”的小项了(就好像你有了四个老婆,大老婆太老了,难看了不要了)接下来就进行操作

order.removeOrderItem(new OrderItem("1"));
orderService.merge(order);

理论上应该可以的但是实际上更新之后还是有四个订单小项(大老婆没有解除掉,这怎么能再娶下一个呢)
大牛们看看呗

#7


JPA规范是不支持级联删除, 不过一般实现方都会提供扩展功能来支持。 
如果你用的是toplink实现包的话, 你就要实现一个DescriptorCustomizer 接口 

public class AccountDescriptorCustomizer implements DescriptorCustomizer { 

    public void customize(ClassDescriptor descriptor) throws Exception { 
        OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName("acct2groups"); 
        if (mapping != null) mapping.setIsPrivateOwned(true); 
    } 

然后在persistence.xml 中properties节点下加入: 
<property name="toplink.descriptor.customizer.包名.Account" value="包名.AccountDescriptorCustomizer"/> 

最后Acct2group 中 @ManyToOne 属性cascade将CascadeType.ALL 改成 {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.MERGE}. 

如果是hibernate的实现的话, 在@OneToMany 
旁边加上: @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_OPTION) 


--------------------------------------------------------------------------------

#8


JPA规范是不支持级联删除, 不过一般实现方都会提供扩展功能来支持。 
如果你用的是toplink实现包的话, 你就要实现一个DescriptorCustomizer 接口 

public class AccountDescriptorCustomizer implements DescriptorCustomizer { 

    public void customize(ClassDescriptor descriptor) throws Exception { 
        OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName("acct2groups"); 
        if (mapping != null) mapping.setIsPrivateOwned(true); 
    } 

然后在persistence.xml 中properties节点下加入: 
<property name="toplink.descriptor.customizer.包名.Account" value="包名.AccountDescriptorCustomizer"/> 

最后Acct2group 中 @ManyToOne 属性cascade将CascadeType.ALL 改成 {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.MERGE}. 

如果是hibernate的实现的话, 在@OneToMany 
旁边加上: @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_OPTION) 


--------------------------------------------------------------------------------

#9


该回复于2012-03-13 16:01:01被版主删除

#1


该回复于2012-03-13 14:49:38被版主删除

#2


这个问题没有叙述清楚,建议楼主重新整理下问题,大家好来跟帖,呵呵呵。

#3


该回复于2012-03-13 14:54:53被版主删除

#4


该回复于2012-03-13 14:54:53被版主删除

#5


嗯,我再来详细描述

有一订单类 Order

public class Order{
 private String ID;
 private Set OrderItems = new HashSet();

/*添加订单项的方法*/
addOrderItem(OrderItem orderItem){
OrderItems.add(orderItem);
}

/*移除订单项的方法*/
removeOrderItem(OrderItem orderItem){
OrderItems.remove(orderItem);
orderItem.setOrder(null);
}

 getXX();setXX();
......
}
还有个订单项
public class OrderItem{
 private String ID;
 private Order order;

public OrderItem(String ID){
 this.ID = ID;
}

 getXX();setXX();
...............
}

订单Order和订单项的关联关系是一对多
一个订单多个订单项,并且订单项里面的订单字段必须存在(就好比是一夫多妻制一样,妻子肯定要有丈夫)


接下来做一保存
Order order = new Order();
order.addOrderItem(new OrderItem("1"));
order.addOrderItem(new OrderItem("4"));
order.addOrderItem(new OrderItem("3"));
order.addOrderItem(new OrderItem("2"));

orderService.persist(Order);

则这个order中有四个小项ID分别为1,2,3,4
现在这个order有想法了,不想要ID为“1”的小项了(就好像你有了四个老婆,大老婆太老了,难看了不要了)接下来就进行操作

order.removeOrderItem(new OrderItem("1"));
orderService.merge(order);

理论上应该可以的但是实际上更新之后还是有四个订单小项(大老婆没有解除掉,这怎么能再娶下一个呢)
大牛们看看呗

#6


嗯,我再来详细描述

有一订单类 Order

public class Order{
 private String ID;
 private Set OrderItems = new HashSet();

/*添加订单项的方法*/
addOrderItem(OrderItem orderItem){
OrderItems.add(orderItem);
}

/*移除订单项的方法*/
removeOrderItem(OrderItem orderItem){
OrderItems.remove(orderItem);
orderItem.setOrder(null);
}

 getXX();setXX();
......
}
还有个订单项
public class OrderItem{
 private String ID;
 private Order order;

public OrderItem(String ID){
 this.ID = ID;
}

 getXX();setXX();
...............
}

订单Order和订单项的关联关系是一对多
一个订单多个订单项,并且订单项里面的订单字段必须存在(就好比是一夫多妻制一样,妻子肯定要有丈夫)


接下来做一保存
Order order = new Order();
order.addOrderItem(new OrderItem("1"));
order.addOrderItem(new OrderItem("4"));
order.addOrderItem(new OrderItem("3"));
order.addOrderItem(new OrderItem("2"));

orderService.persist(Order);

则这个order中有四个小项ID分别为1,2,3,4
现在这个order有想法了,不想要ID为“1”的小项了(就好像你有了四个老婆,大老婆太老了,难看了不要了)接下来就进行操作

order.removeOrderItem(new OrderItem("1"));
orderService.merge(order);

理论上应该可以的但是实际上更新之后还是有四个订单小项(大老婆没有解除掉,这怎么能再娶下一个呢)
大牛们看看呗

#7


JPA规范是不支持级联删除, 不过一般实现方都会提供扩展功能来支持。 
如果你用的是toplink实现包的话, 你就要实现一个DescriptorCustomizer 接口 

public class AccountDescriptorCustomizer implements DescriptorCustomizer { 

    public void customize(ClassDescriptor descriptor) throws Exception { 
        OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName("acct2groups"); 
        if (mapping != null) mapping.setIsPrivateOwned(true); 
    } 

然后在persistence.xml 中properties节点下加入: 
<property name="toplink.descriptor.customizer.包名.Account" value="包名.AccountDescriptorCustomizer"/> 

最后Acct2group 中 @ManyToOne 属性cascade将CascadeType.ALL 改成 {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.MERGE}. 

如果是hibernate的实现的话, 在@OneToMany 
旁边加上: @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_OPTION) 


--------------------------------------------------------------------------------

#8


JPA规范是不支持级联删除, 不过一般实现方都会提供扩展功能来支持。 
如果你用的是toplink实现包的话, 你就要实现一个DescriptorCustomizer 接口 

public class AccountDescriptorCustomizer implements DescriptorCustomizer { 

    public void customize(ClassDescriptor descriptor) throws Exception { 
        OneToManyMapping mapping = (OneToManyMapping) descriptor.getMappingForAttributeName("acct2groups"); 
        if (mapping != null) mapping.setIsPrivateOwned(true); 
    } 

然后在persistence.xml 中properties节点下加入: 
<property name="toplink.descriptor.customizer.包名.Account" value="包名.AccountDescriptorCustomizer"/> 

最后Acct2group 中 @ManyToOne 属性cascade将CascadeType.ALL 改成 {CascadeType.REFRESH, CascadeType.MERGE, CascadeType.MERGE}. 

如果是hibernate的实现的话, 在@OneToMany 
旁边加上: @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_OPTION) 


--------------------------------------------------------------------------------

#9


该回复于2012-03-13 16:01:01被版主删除