首页 > 解决方案 > 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 或与动态更新过程相关,但结果还是一样,变量“描述”仍然为空。

有什么建议吗?

标签: springhibernatejsp

解决方案


问题在于控制器的编写方式:在执行 saveData 时创建并填充一个新的模型实例。

您可以将代码更新为如下所示。现在在 POST 上,模型实例将是从 getModel() 返回的实例,而不是新实例,并且只有传入请求中指定的值将被更新。我们还可以更新 GET 以使用相同的代码来填充模型。

基本上然后:

  • 在 GET 上 - 将通过调用 @ModelAttribute 为 UI 填充模型
  • 在 POST 上 - 模型将被填充,返回的模型实例将被传递给 saveData();

看:

https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-modelattrib-method-args

@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();
    }
}

推荐阅读