Spring 4 MVC updates entity before modifying post request

Controller:

@PreAuthorize("@securityService.isAdminForSurvey(principal.user, #survey)")
@RequestMapping(value = "/service-management/surveys/{survey}/edit", method = RequestMethod.GET)
public String editSurvey(@PathVariable Survey survey, Model model) {

    model.addAttribute("survey", survey);


@PreAuthorize("@securityService.isAdminForSurvey(principal.user, #survey)")
@RequestMapping(value = "/service-management/surveys/{survey}/edit", method = RequestMethod.POST)
public String editSurvey(@ModelAttribute("survey") Survey survey, SessionStatus sessionStatus) {
        surveyService.update(survey);

Converter:

@Component
public class SurveyConverter implements Converter<String, Survey> {
    @Autowired
    private SurveyService surveyService;
    @Override
    public Survey convert(String hash){
        try {
            return surveyService.getSurveyByHash(hash);
        }catch(NumberFormatException e){
            return null;
    }

}

}

When I send post request with modified data from spring form, somehow object is updated before calling to security service. Repository returns already updated survey entity with values from the form before even calling save method. How it's even possible?

EDIT for showing that security service methods fires here is some logs with method calls queue:

2016-04-12 15:08:44.282  INFO 12496 --- [nio-8080-exec-8] ....service.SurveyServiceImpl       : [.....service.SurveyServiceImpl.getSurveyByHash(SurveyServiceImpl.java:87)]
2016-04-12 15:08:44.290  INFO 12496 --- [nio-8080-exec-8] ....security.SecurityService    : [.....security.SecurityService.isAdminForSurvey(SecurityService.java:38)]
2016-04-12 15:08:44.295  INFO 12496 --- [nio-8080-exec-8] ....controller.SurveyController     : [....controller.SurveyController.editSurvey(SurveyController.java:362)]

Issue investigation lead to next conclusion:

  • #survey parameter in @PreAuthorize have been misused because it aimed to model attribute, not to path variable as was expected.
  • Form from jsp page was automatically binded by spring to survey object because both @PathVariable and @ModelAttribute had same names.
  • Solution is to use different names for @PathVariable and @ModelAttribute . In that case converter behaves correctly - converts value from url, and @ModelAttribute object contains values from the form. Can someone light up why Spring behaves this way? Similar behavior were observed on Spring 3.

    same logs with sql

    2016-04-13 00:41:18.636  INFO 4445 --- [nio-8080-exec-6] .....service.SurveyServiceImpl       : [.....service.SurveyServiceImpl.getSurveyByHash(SurveyServiceImpl.java:87)]
    Hibernate: 
    select
        survey0_.id as id1_11_,
        survey0_.hash as hash19_11_,
        survey0_.version as version48_11_ 
    from
        survey survey0_ 
    where
        survey0_.hash=?
    Hibernate: 
    select
        adminsurve0_.id as id1_0_0_,
        adminsurve0_.enable_edit as enable_e2_0_0_,
        adminsurve0_.survey_id as survey_71_0_0_ 
    from
        admin_survey_permissions adminsurve0_ 
    where
        adminsurve0_.survey_id=?
    2016-04-13 00:41:18.646  INFO 4445 --- [nio-8080-exec-6] ....security.PtspSecurityService    : [.....security.PtspSecurityService.isAdminForSurvey(PtspSecurityService.java:38)]
    Hibernate: 
    select
        'true' as col_0_0_ 
    from
        users user0_ 
    where
        user0_.id=? 
        and (
            user0_.is_super_admin=true 
            or user0_.is_admin=true 
        )
    2016-04-13 00:41:18.653  INFO 4445 --- [nio-8080-exec-6] .....controller.SurveyController     : [.....controller.SurveyController.editSurvey(SurveyController.java:362)]
    Hibernate: 
    select
        adminsurve0_.id as id1_0_,
        adminsurve0_.enable_edit as enable_e2_0_,
        adminsurve0_.survey_id as survey_71_0_ 
    from
        admin_survey_permissions adminsurve0_ 
    left outer join
        survey survey1_ 
            on adminsurve0_.survey_id=survey1_.id 
    where
        survey1_.id=?
    

    NOTE:

    sql output were shortened because object contains a lot of fields with some data to fetch on.

    链接地址: http://www.djcxy.com/p/92558.html

    上一篇: JavaScript正则表达式电子邮件验证

    下一篇: Spring 4 MVC在修改post请求之前更新实体