spring - Sping MVC和hibernate:jsp中未声明的变量在保存时变为null
问题描述
我刚刚使用 Spring 框架和休眠创建了我的简单 Web 应用程序。但是当我的数据库发生事务时,我面临着关键问题。当我尝试更新我的对象时,未声明的变量在保存到数据库时变为空。
我将用一个例子来解释它。
模型.java:
public class Model implements Serializable {
private int id;
private String firstName;
private String lastName;
private String description;
//setter getter
}
ModelDaoImpl.java:
@Repository("modelDao")
public class ModelDaoImpl implements ModelDao {
@Autowired
SessionFactory sessionFactory;
public Model create (Model model) throws Exception {
this.sessionFactory.getCurrentSession().save(model);
return model;
}
public Model update (Model model) throws Exception {
this.sessionFactory.getCurrentSession().update(model);
return model;
}
public Model get (Serializable id) throws Exception {
return (Model) this.sessionFactory.getCurrentSession().get(Model.class, id);
}
}
模型服务Impl.java:
@Service("modelService")
public class ModelServiceImpl implements ModelService {
@Autowired
modelDao modelDao;
@Transactional
public Model create (Model model) throws Exception {
return modelDao.create(model);
}
@Transactional
public Model update (Model model) throws Exception {
return modelDao.udpdate(model);
}
@Transactional
public Model get (Serializable id) throws Exception {
return modelDao.get(id);
}
}
模型控制器.java:
@Controller
public class ModelController {
@Autowired
ModelService modelService
@RequestMapping(value="/editModel", method.RequestMethod.GET)
public String formCreator(ModelMap model, HttpServletRequest request) {
Integer id = new Integer(request.getParameter("id"));
Model modelData = new Model();
if (id != null) {
modelData = modelService.get(id);
}
model.addAttribute("modelData", modelData);
return "editModel"
}
@RequestMapping(value="/saveModel", method.RequestMethod.POST)
public String saveData(@ModelAttribute("modelData") Model modelData) {
if (modelData.getId() == null) {
modelService.create(modelData);
} else {
modelService.update(modelData);
}
return "redirect:/modelList";
}
//SKIP FOR GET MODEL LIST AND GET MODEL DETAIL
}
编辑模型.jsp:
<form:form action="${pageContext.request.contextPath}/saveModel" method="POST" modelAttribute="modelData">
<table>
<form:hidden path="id"/>
<tr>
<td>First Name:</td>
<td><form:input path="firstName"/></td>
</tr>
<tr>
<td>Last Name:</td>
<td><form:input path="lastName"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Save"></td>
</tr>
</table>
</form:form>
从 jsp 页面我们看到我没有声明变量“描述”,但是当更新我现有的数据时,变量“描述”变为空。我曾尝试使用@DynamicUpdate 或与动态更新过程相关,但结果还是一样,变量“描述”仍然为空。
有什么建议吗?
解决方案
问题在于控制器的编写方式:在执行 saveData 时创建并填充一个新的模型实例。
您可以将代码更新为如下所示。现在在 POST 上,模型实例将是从 getModel() 返回的实例,而不是新实例,并且只有传入请求中指定的值将被更新。我们还可以更新 GET 以使用相同的代码来填充模型。
基本上然后:
- 在 GET 上 - 将通过调用 @ModelAttribute 为 UI 填充模型
- 在 POST 上 - 模型将被填充,返回的模型实例将被传递给 saveData();
看:
@Controller
public class ModelController {
@Autowired
ModelService modelService
@RequestMapping(value="/editModel", method.RequestMethod.GET)
public String formCreator(HttpServletRequest request) {
return "editModel"
}
@RequestMapping(value="/saveModel", method.RequestMethod.POST)
public String saveData(@ModelAttribute("modelData") Model model) {
//you can have 1 method in your service and DAO
//DAO can use saveOrUpdate() method of session;
modelService.persist(model);
return "redirect:/modelList";
}
@ModelAttribute("modelData")
public Model getModel(@RequestParam(name = "id", required = false)Integer id){
return id != null ? modelService.get(id) : new Model();
}
}
推荐阅读
- java - 使用java拆分获取值
- react-redux - 不断不得不杀死工作进程来启动我的 Phoenix 应用程序
- swift - Swift 动态动画,后跟属性动画师
- java - 如何获取 Spectron 测试结果并将其传递给外部测试(例如,Ucumber-Junit 测试)
- powershell - 获取 NetFirewallRule 用户{GIUD}
- css - 具有可变高度的css flex网格
- react-native - 如何在测试函数中模拟常量值
- python - 在两个嵌套函数中并行化 python 代码
- vue.js - 如何调用我的 Vue.js 插件中声明的函数
- xamarin - 如何在 xamarin mvvmcross 中为我的按钮创建“ontouch”事件?