JPA执行SQL(主从添加)不提交事务问题

Java 专栏收录该内容
10 篇文章 0 订阅

前段时间做项目遇到了一个问题,这里总结一下
环境
需要添加合同主表信息与从表信息(从表中需要存储主表id),因为bean在另一个项目中,但是却公用数据库,所以我们不能使用jpasave(对象) 方法。只能写sql,然后调用对应的createNativeQuery的方法。问题出现了。。。
因为是在service中处理,service的一个方法因为事务的原因将整个方法都走完才commit
坑爹的来了 。。。我先添加主表信息,然后再倒序查询主表,获取id 赋值给从表,但是无论如何我获取的都是上一个主表记录的id 但是控制台已经显示执行了主表插入的sql….就是因为事务的原因 他并没有commit 所以也没有id
解决办法
1.首先我尝试将主从添加写到两个service中,但是因为项目逻辑的原因 他们都需要在另外一个serivice中调用,所以还是在一个事务里面没有提交
2.我后来想到了flushrefresh 同步缓存和数据库 ,让他强制提交,最终呢还是不行
3.(真正的解决办法)
最终我才用JdbcTemplate 问题轻松解决


            List<TContact2> contracts = this.supplierInfoWebServiceDao.search2(TContact2.class,"select *  from contactbuy where id = "+id);
            if(null==contracts){
                throw new BusinessException("获取合同信息出错");
            }
            if(contracts.size()>0){
                final TContact2 contract = contracts.get(0);
                KeyHolder keyHolder = new GeneratedKeyHolder();
                dao.getJdbcTemplate().update(new PreparedStatementCreator() {
                    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
                        StringBuffer sbMain = new StringBuffer("");
                        sbMain.append("INSERT INTO mxinterface_purchasecontract  ");
                        sbMain.append("(contactcode,contractName,contractTotalMoney,projectDepartmentCode,projectDepartmentName,returnMessage,returnTime,success,supplcode,supplname) ");
                        sbMain.append("values(?,?,?,?,?,?,?,?,?,?)");
                        PreparedStatement ps = con.prepareStatement(sbMain.toString(), Statement.RETURN_GENERATED_KEYS);
                        ps.setString(1, contract.getContactcode());
                        ps.setString(2, contract.getContractName());
                        ps.setString(3, contract.getContractTotalMoney());
                        ps.setString(4, contract.getProjectInterfaceCode());
                        ps.setString(5, contract.getPurchaseDeptName());
                        ps.setString(6, "");
//                      ps.setString(7, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                        ps.setString(7, null);
                        ps.setString(8, "0");
                        ps.setString(9, contract.getSupplcode());
                        ps.setString(10, contract.getSupplname());
                        return ps;
                    }
                }, keyHolder);

                // 主表ID
                final int approveID = Integer.valueOf(keyHolder.getKeyList().get(0).get("GENERATED_KEY").toString());

                List<TContactDetail2> contractDetails = this.supplierInfoWebServiceDao.search2(TContactDetail2.class,"select *  from contactbuydetail where contactid = "+id);
                if(null!=contractDetails&&contractDetails.size()>0){
                    for(TContactDetail2 detail:contractDetails){
                        String sql = "INSERT INTO mxInterface_purchaseContractDetail VALUES(NULL,"+approveID+","
                            + "'"+detail.getContactwzcode()+"','"+detail.getContactwzdetail()+"','"+detail.getContactwzmodel()+"','"+detail.getContactwzname()+"',"
                            + ""+detail.getContactwznum()+",'"+detail.getContactwzunit()+"',"+detail.getContractMoney()+","+detail.getContractPrice()+")";                      
                        dao.getJdbcTemplate().update(sql);
                    }
                }
            }

这个方法可以直接返回新添加的主表Id,类似于 jpasave(对象) 方法 也会直接commit
当然这个方法可以直接返回Id,另外我发现直接用JdbcTemplate 的实例对象update 也会提交事务,只是Id 需要我们再查一次而已

最后采用3方法,我估计JdbcTemplatejpa 可能底层实现不一样吧
具体的实现原理和其中的原因还希望大家指出
另外如果有更好的方法也请指教 ~~~

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值