Dorado7与@ManyToMany的矛盾分析
在Dorado7开发时,通过UpdateAction提交数据,默认只会提交DataSet中DirtyTree,这样如果子对象数据未发生修改时是不会提交的,后台拿到的子对象为空。
如果两对象之间,通过JPA注解@ManyToMany配置了级联关系,那么在被控方数据(子对象)未发生修改时提交保存主控方数据而时,就会导致关系数据丢失。
例:Product1和SaleAgencyPayAccount1对象关系为ManyToMany,SaleAgencyPayAccount1为主控方,通过UpdateAction提交SaleAgencyPayAccount1时,
如果products未发生修改时并且关系表OC_PRODUCT_SAPA1存在数据,那么保存后关系表OC_PRODUCT_SAPA1中数据就会发生丢失。
- 原因:是ManyToMany关系须要有一个主控方来维护关系,提交对象中products为空,主控方便以为关系被删所以就会去删除中间表数据。
- 二种破解方法:
- 化ManyToMany为2个ManyToOne和OneToMany
- 后台方法判断,当products为空时,再查一次数据,使用session.merge()方法保存数据.
Product1
@Entity @Table(name = "OC_PRODUCT1") public class Product1 { @Id @PropertyDef(label = "主键") @Column(name = "ID_", length = 36) private String id; @PropertyDef(label = "产品简称") @Column(name = "PRODUCT_SHORT_NAME_") private String productShortName; @ManyToMany(mappedBy = "products", fetch = FetchType.EAGER) @Fetch(FetchMode.SUBSELECT) private List<SaleAgencyPayAccount1> saleAgencyPayAccounts; ...... }
SaleAgencyPayAccount1
@Entity @Table(name = "OC_SALE_AGENCY_PAY_ACCOUNT1") public class SaleAgencyPayAccount1 { @Id @PropertyDef(label = "主键") @Column(name = "ID_") private String id; @Column(name = "REMARK_") @PropertyDef(label = "备注/用途") private String remark; @ManyToMany(cascade = CascadeType.REFRESH, fetch=FetchType.EAGER) @JoinTable(name = "OC_PRODUCT_SAPA1", joinColumns ={@JoinColumn(name = "SALE_AGENCY_PAY_ACCOUNT_ID_", referencedColumnName = "ID_", insertable = false, updatable = false)}, inverseJoinColumns = { @JoinColumn(name = "PRODUCT_ID_", referencedColumnName = "ID_", insertable = false, updatable = false)}) @PropertyDef(label = "销售机构缴款账户") private List<Product1> products; ...... }
岁月留痕