联合主键
2017-04-24 19:05 绿贝 阅读(389) 评论(0) 编辑 收藏 举报近期找一个数据不一致的问题,花了一周时间找bug,感觉很经典。虽然是填离职同事留下的坑。由于插入了很多错误数据,还需要一周的时间去手动修改错误数据(1千多条错误数据)。很坑啊有木有!!
他的代码是这样的:
@Entity public class PaymentDetailVO implements Serializable { @Id public Long duesdetailid; public String paymenttype; @Id public String paymethod; public BigDecimal payamount; }
// 前面代码省略 paymentdetailsql.append("select t.id as duesdetailid,") .append(" '1' as paymenttype,") .append(" ddl.value as paymethod,") .append(" (sum(ts.price)-nvl(sum(tr.returnamount),0)-nvl(sum(tc.ticketprice),0)) as payamount") .append(" from Ticketturnoverdetail t ") .append(" left join ticketsell ts on t.id = ts.turnoverdetailid ") .append(" left join ticketreturn tr on t.id=tr.turnoverdetailid ") .append(" left join ticketcancel tc on t.id=tc.turnoverdetailid ") .append(" left join digitaldictionarydetail ddl on ddl.digitaldictionaryid=50 and ddl.code=ts.paymethod") .append(" where (ts.paymethod <> '0' and ts.paymethod <> '2' and ts.paymethod <> '3') and t.id=:id") .append(" group by ddl.value,'1',t.id") .append(" union all") .append(" select t.id as duesdetailid,") .append(" '1' as paymenttype,") .append(" ddl.value as paymethod,") .append(" (sum(ts.price)-nvl(sum(tr.returnamount),0)-nvl(sum(tc.ticketprice),0)) as payamount") .append(" from Ticketturnoverdetail t ") .append(" left join ticketsellagent ts on t.id = ts.turnoverdetailid ") .append(" left join ticketreturn tr on t.id=tr.turnoverdetailid ") .append(" left join ticketcancel tc on t.id=tc.turnoverdetailid ") .append(" left join digitaldictionarydetail ddl on ddl.digitaldictionaryid=50 and ddl.code=ts.paymethod") .append(" where (ts.paymethod <> '0' and ts.paymethod <> '2' and ts.paymethod <> '3') and t.id=:id") .append(" group by ddl.value,'1',t.id"); Query ticketquery = JPA.em().createNativeQuery(paymentdetailsql.toString(),PaymentDetailVO.class); ticketquery.setParameter("id", ticketturnoverdetail.getId()); List<PaymentDetailVO> paymentdetaillist = new ArrayList<PaymentDetailVO>(); try { paymentdetaillist = ticketquery.getResultList(); } catch (Exception e) { e.printStackTrace(); play.Logger.error("=============:%s", e.getMessage()); } for(PaymentDetailVO paymentdetail : paymentdetaillist){ PaymentDetail _paymentdetail = new PaymentDetail(); _paymentdetail.duesdetailid=paymentdetail.duesdetailid; _paymentdetail.paymenttype=paymentdetail.paymenttype; _paymentdetail.paymethod=paymentdetail.paymethod; _paymentdetail.payamount=paymentdetail.payamount; _paymentdetail.createtime=new Date(); _paymentdetail.save(); } //后面代码省略
看出问题了么?他使用
duesdetailid和paymethod作为联合主键,但是查询语句用的是union all 将2个group by 给连接起来。插入paymentdetail 的时候jpa认为是第一条和第二条是同一条数据,导致第一条数据插入了2次,而第二条没有插入。
如何修改呢?只要把外面再套一层group by 就行了。然后paymenttype也要加入联合主键。前面加上@Id