Controller中的@ModelAttribute不会自动增加ID

时间:2015-05-16 13:14:53

标签: spring hibernate modelattribute

我正在开发基于Spring web的项目,我遇到了将模型对象返回到要填充的JSP文件的@ModelAttribute,然后将其传递给控制器​​函数,然后将数据保存到数据库中。让我给你看一些代码。

这是我的软件工程课程项目,更多详细信息代码可在github上找到: https://github.com/IYTECENG316SoftwareEngineering/reddit

@Controller
    public class MessageController {



     @ModelAttribute("privateMessage")
         public PrivateMessage constructPrivateMessage() {
         return new PrivateMessage();
     }




    @RequestMapping(value = "/message/{id}", method = RequestMethod.POST, params = "sendMessage")
        public String doSendMessage(Model model, @PathVariable("id") int id,
            @Valid @ModelAttribute("privateMessage") PrivateMessage privateMessage, BindingResult result,Principal principal) {

            if (result.hasErrors()) {
                return showMessage(model,id);
            }


         User messageOwner = userService.findOne(principal.getName());
                //I need to create new instance of PrivateMessage because
                //(@ModelAttribute("privateMessage") PrivateMessage privateMessage) this gives always same ID.
                PrivateMessage message = new PrivateMessage();
                message.setMessage(privateMessage.getMessage());
                message.setUser(messageOwner);

            PrivateMessageConversation conversation = messageService.findOneWithMessages(id);
            message.setPrivateMessageConversation(conversation);
            messageService.save(message);

            return "redirect:/message/"+message.getID()+".html";
        }

    }

PrivateMessage对象发送到jsp文件,并使用@ModelAttribute填充发送回doSendMessage函数。对象带有填充(所有输入完全写入对象)但唯一的问题是它的ID不会自动递增。还有一个我想要显示的代码。我们对主题使用相同的模板,它完美地工作。这是代码;

@Controller
public class UserController {


@ModelAttribute("topic")
    public Topic contructTopic() {
        return new Topic();
    }
@ModelAttribute("entry")
public Entry contructEntry() {
    return new Entry();
}

@RequestMapping(value = "/account", method = RequestMethod.POST)
    public String doAddNewTopic(Model model,
            @Valid @ModelAttribute("topic") Topic topic,
            BindingResult resultTopic, Principal principal,
            @Valid @ModelAttribute("entry") Entry entry,
            BindingResult resultEntry,
            @RequestParam("topic_category") String category_string) {
        System.out.println(principal.getName() + " " + category_string + " "
                + topic.getTitle() + " " + entry.getDescription());

        if (resultTopic.hasErrors()) {
            return account(model, principal);
        }
        if (resultEntry.hasErrors()) {
            return account(model, principal);
        }

        String name = principal.getName();

        Category category = categoryService.findByName(category_string);
        topic.setCategory(category);
        topicService.save(topic);

        entry.setTopic(topic);
        entry.setPublishedDate(new LocalDateTime());
        entryService.save(entry, name);

        return "redirect:/topic/" + topic.getId() + ".html";
    }

}

以上代码完美无缺。主题和入口对象发送到jsp,它们填充并发送回控制器,所有属性都很好,ID会自动递增。我们无法想象为什么第一个不工作。

注意:我们正在使用Hibernate,Spring Data JPA和Tiles

1 个答案:

答案 0 :(得分:0)

在您的第一个控制器(MessageController)中,您正在构建PrivateMessage的新实例并保存该实例。 hibernate生成的id将在那里更改。然后,您正在使用路径模式(redirect:/message/{id}.html)进行重定向。该模式将使用调用方法doSendMessage的原始ID进行扩展。

在您的第二个(工作)控制器中,您没有创建Topic的新实例,因此在保存主题后,主题中包含hibernate分配的ID。之后,您也没有使用弹簧路径扩展,而是使用新的id手动构建路径。

更改您的第一个控制器
return "redirect:/message/{id}.html";

return "redirect:/message/" + message.getId() + ".html";

return UriComponentsBuilder.fromUriString("redirect:/message/{id}.html")
    .buildAndExpand(message.getId())
    .encode()
    .toUriString()