getHibernateTemplate 修改和删除操作失败的解决办法

本文介绍了一位开发者在使用SSH(SpringStrutsHibernate)架构的小型项目中遇到的CRUD操作问题,特别是在业务数据修改和删除时失败的情况。通过检查Spring的事务配置,最终发现事务切面配置错误导致的问题,并给出了具体的解决方案。




问题描述:



    近期根据需求架构了一个小型项目,由于是公司内部使用,没有考虑三高(即高并发、高可用、高扩展),所以使用了SSH(Spring\Struts\Hibernate)进行开发的,主体架构完成后,开始对业务进行CRUD的操作,DAO实现层都是继承自 HibernateDaoSupport 并实现了DOA接口层,其中的部分CRUD通过调用 Hibernate 的模板 getHibernateTemplate 实现的。

    可以正常执行业务数据的添加操作,但是在对业务数据进行修改和删除时失败,但页面和后台无异常的日志输出,搞了许久还是失败,只好找度娘和谷哥了,上面有类似的问题,但是解决方案没有一个。

事务管理器配置如下图:



事务通知配置如下图:



事务切面配置如下图:





解决方案:

    最后,只能头痛的盯着Spring的事务配置文件(初步判定为事务未提交),看了一遍又一遍(看了无数遍),最后突然犹如天降神灵,脑洞大开,发现我的事务切面配置错了,字母写错了一个!!!如下图:



终于找到问题了,迫不及待的启动服务器进行测试,成功了!!!








    好了,关于 getHibernateTemplate 修改和删除操作失败 就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。
歇后语:“ 共同学习,共同进步 ”,也希望大家多多关注CSND的IT社区。

请结合上面代码分析下面代码:/* */ public void withdrawRuncardByMode(ErcMastForm ercMastForm, String mode) /* */ { /* 943 */ List steps = new ArrayList(); /* 944 */ if (null != ercMastForm.getWorkflowId()) { /* 945 */ steps = findByNamedQuery("findCurrentStepByEntryId", new Object[] { ercMastForm.getWorkflowId() }); /* */ } /* */ /* 948 */ for (int i = 0; i < steps.size(); i++) { /* 949 */ HibernateCurrentStep step = (HibernateCurrentStep)(HibernateCurrentStep)steps.get(i); /* 950 */ getHibernateTemplate().delete(step); /* */ } /* */ /* 953 */ List processLogs = ercMastForm.getProcessLogs(); /* 954 */ ErcProcessLog lastLog = (ErcProcessLog)processLogs.get(processLogs.size() - 1); /* */ /* 957 */ if (("Completed".equalsIgnoreCase(mode)) || ("Withdrew".equalsIgnoreCase(mode))) { /* 958 */ IProcessLog logForJob = ercMastForm.createProcessLog(); /* 959 */ logForJob.setStatus(mode); /* 960 */ logForJob.setCaller("System"); /* 961 */ logForJob.setFromDate(lastLog.getThruDate()); /* 962 */ logForJob.setThruDate(new Date()); /* 963 */ logForJob.setActionName(""); /* 964 */ logForJob.setRemark("System Auto Job"); /* 965 */ if ("Completed".equalsIgnoreCase(mode)) { /* 966 */ Date now = new Date(); /* 967 */ ercMastForm.setCompletedDate(WeekUtil.getCompletedDate(now)); /* 968 */ ercMastForm.setMonth(String.valueOf(WeekUtil.getMonth(now))); /* 969 */ ercMastForm.setYear(String.valueOf(WeekUtil.getYear(now))); /* 970 */ ercMastForm.setWeek(String.valueOf(WeekUtil.getWeek(now))); /* */ } /* 972 */ ercMastForm.addProcessLog(logForJob); /* */ } /* */ else { /* 975 */ IProcessLog log = ercMastForm.createProcessLog(); /* 976 */ log.setActionName("Withdraw"); /* 977 */ log.setOwner(""); /* 978 */ log.setFromDate(lastLog.getThruDate()); /* 979 */ log.setThruDate(new Date()); /* 980 */ if (mode.equalsIgnoreCase("admin")) { /* 981 */ log.setCaller(RemoteUser.get().getUserLoginId()); /* */ /* 983 */ log.setStatus(ercMastForm.getStatus()); /* 984 */ ercMastForm.setStatus("Withdrew"); /* 985 */ log.setRemark("Admin had changed the runcard status!"); /* 986 */ } else if (mode.equalsIgnoreCase("keyInClose")) { /* 987 */ log.setActionName("keyInClose"); /* 988 */ log.setCaller(RemoteUser.get().getUserLoginId()); /* 989 */ log.setStatus(ercMastForm.getStatus()); /* 990 */ log.setRemark(ercMastForm.getKeyInRemark()); /* 991 */ ercMastForm.setStatus("Completed"); /* 992 */ sendMailToApplicant(ercMastForm); /* 993 */ } else if (mode.equalsIgnoreCase("keyInWithdraw")) { /* 994 */ log.setCaller(RemoteUser.get().getUserLoginId()); /* 995 */ log.setStatus(ercMastForm.getStatus()); /* 996 */ log.setRemark(ercMastForm.getKeyInRemark()); /* 997 */ ercMastForm.setStatus("Withdrew"); /* 998 */ sendMailToApplicant(ercMastForm); /* */ } /* 1000 */ else if (mode.equalsIgnoreCase("unlock")) { /* 1001 */ log.setCaller(RemoteUser.get().getUserLoginId()); /* 1002 */ log.setStatus(ercMastForm.getStatus()); /* 1003 */ log.setRemark("Withdraw this runcard because its porduct id is not match with MES"); /* 1004 */ ercMastForm.setStatus("Withdrew"); /* 1005 */ ercMastForm.setLockFlag("pass"); /* 1006 */ } else if ("changeStatus".equalsIgnoreCase(mode)) { /* 1007 */ log.setActionName("ChangeStatus"); /* 1008 */ log.setCaller(RemoteUser.get().getUserLoginId()); /* 1009 */ log.setRemark("Admin had changed the runcard's status"); /* 1010 */ log.setStatus(ercMastForm.getStatus()); /* */ } /* */ else { /* 1013 */ log.setCaller(ercMastForm.getApplicant()); /* 1014 */ log.setStatus(ercMastForm.getStatus()); /* 1015 */ ercMastForm.setStatus("Applicant Withdrew RunCard"); /* 1016 */ log.setRemark(ercMastForm.getApplicantRemark()); /* */ } /* 1018 */ ercMastForm.addProcessLog(log); /* */ } /* 1020 */ ercMastForm.setWorkflowFinishDate(new Date()); /* 1021 */ update(ercMastForm); /* */ }
最新发布
09-05
Spring 中使用 `getHibernateTemplate().save(bean)` 保存实体对象时,**Hibernate 会直接将对象插入数据库**。如果插入成功,会返回一个可表示该实体持久化标识的对象(如 `Serializable id`);如果失败(如违反约束、数据库连接失败等),会抛出异常。 --- ### ✅ 如何判断 `save()` 是否成功? 你可以通过以下方式判断保存是否成功: #### ✅ 方法一:通过返回值判断 ```java try { Serializable id = getHibernateTemplate().save(bean); if (id != null) { // 保存成功,id 是插入记录的主键 System.out.println("保存成功,主键为:" + id); } else { // 保存失败,但没有抛出异常,视业务而定 System.out.println("保存失败"); } } catch (Exception e) { // 捕获异常,说明保存失败 System.out.println("保存异常:" + e.getMessage()); } ``` - `save()` 返回的是插入记录的主键(如 `Long`, `Integer`, `String` 等); - 如果返回 `null`,说明保存失败(但通常失败会抛出异常); - 建议始终使用 `try-catch` 捕获异常,确保程序健壮性。 --- #### ✅ 方法二:捕获异常 + 日志记录(推荐) ```java try { getHibernateTemplate().save(bean); // 没有异常,说明保存成功 System.out.println("保存成功"); return true; } catch (Exception e) { // 记录日志 logger.error("保存失败,错误信息:", e); return false; } ``` - 这种方式更推荐,因为即使返回了 id,也有可能插入过程中发生异常; - 使用日志记录异常信息,便于排查问题。 --- ### 🔍 示例代码(封装为方法) ```java public boolean savePayMes(PayMes bean) { try { Serializable id = getHibernateTemplate().save(bean); if (id != null) { System.out.println("保存成功,主键:" + id); return true; } else { System.out.println("保存失败,未分配主键"); return false; } } catch (Exception e) { System.out.println("保存异常:" + e.getMessage()); e.printStackTrace(); return false; } } ``` --- ### 💡 注意事项 1. **事务管理**:确保 `save()` 操作是在事务中执行的,否则可能不会立即写入数据库; 2. **主键策略**:如果主键是自动生成的(如 `@GeneratedValue`),那么 `save()` 返回的 id 应该是非空; 3. **HibernateTemplate 的弃用**: - `HibernateTemplate` 是 Spring 旧版本中封装的工具类,在 Spring Boot 中已被弃用; - 推荐使用 `Hibernate SessionFactory` 或 `JPA 的 EntityManager`; - 如果你使用的是 Spring Boot + JPA,可以使用 `repository.save()`,它返回的是保存后的实体对象。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechBro华仔

日拱一卒无有尽,功不唐捐终入海

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值