【问题标题】:@ModelAttribute in Controller does not auto increment ID控制器中的@ModelAttribute 不会自动增加 ID
【发布时间】:2023-04-07 11:53:02
【问题描述】:

我正在开发基于 Spring Web 的项目,我在使用 @ModelAttribute 时遇到问题,它会将模型对象返回给 JSP 文件以进行填充,然后将其传递给控制器​​函数,然后将数据保存到数据库中。让我给你看一些代码。

这是我的软件工程课程项目,更详细的信息代码可在 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

【问题讨论】:

    标签: spring hibernate modelattribute


    【解决方案1】:

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

    在您的第二个(工作)控制器中,您没有创建Topic 的新实例,因此在保存主题后,休眠分配的 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()
    

    【讨论】:

    • 嗨@DirkLachowski。感谢您的关注。您是对的,我在重定向方面遇到了一些“问题”,但它们是有效的。无论如何,我按照您的建议更改为 `return "redirect:/message/"+ message.getId() + ".html"; ` 我认为我的重定向现在很好。是的,在我的 MessageController 中,我创建了 PrivateMessage 的新实例,因为它总是带有相同的 ID。我希望我能正确地告诉我我的问题。另一方面,第二个(工作)控制器我不创建新实例,因为它带有自动生成的 ID,现在我试图理解为什么一个工作而另一个不工作。
    猜你喜欢
    • 2019-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-17
    • 2013-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多