Hibernate保存或更新问题

时间:2015-04-20 11:36:09

标签: hibernate spring-mvc

当我从/ createmessage页面保存商品时,我遇到了一个问题。我正在使用hibernate来保存或删除它,如果要更新或创建消息(session().saveOrUpdate(message)),它会自动引发。目前,这会每次都创建一条新消息而不会更新

消息模型

@Entity
@Table(name="messages")
public class Message
{
    @Id
    @GeneratedValue
    private int id;

    @ManyToOne
    @JoinColumn(name="username")
    private User user;

    @NotBlank(groups={PersistenceValidationGroup.class,FormValidationGroup.class})
    @Size(min=20, max=200, groups={PersistenceValidationGroup.class,FormValidationGroup.class})
    @Column(name="text")
    private String text;

    public Message()
    {
        this.user = new User();
    }

    public Message(User user, String text) 
    {
        this.user = user;
        this.text = text;
    }

    public Message(int id, User user, String text) 
    {
        this.id = id;
        this.user = user;
        this.text = text;
    }

讯息表

<h2>Messages</h2>

<table class="messagesTable">
    <tr>
        <th align="left"><b>Id</b></th>
        <th align="left"><b>Username</b></th>
        <th align="left"><b>First Name</b></th>
        <th align="left"><b>Last Name</b></th>
        <th align="left"><b>Email</b></th>
        <th align="left"><b>Text</b></th>
    </tr>

    <c:forEach var="row" items="${messages}">
        <tr>
            <td>${row.id}</td>
            <td>${row.user.username}</td>
            <td>${row.user.firstName}</td>
            <td>${row.user.lastName}</td>
            <td>${row.user.email}</td>
            <td>${row.text}</td>
                <c:if test="${row.user.username==loggedInUser}">
                    <td>
                        <form action='<c:url value="/createmessage"></c:url>' method="post">
                            <input type="hidden" id="edit" name="edit" value="${row.id}"></input> 
                            <input type="submit" value="Edit Message"></input>  
                        </form>
                    </td>
                    <td>
                        <form action='<c:url value="/boardroom"></c:url>' method="post">
                            <input type="hidden" id="delete" name="delete" value="${row.id}"></input> 
                            <input type="submit" id="deletebutton" value="Delete Message"></input>  
                        </form>
                    </td>
                </c:if>
        </tr>
    </c:forEach>
</table>

控制器

@RequestMapping(value="/boardroom")
        public String showMessages(Model model, Principal principal, 
                @RequestParam(value = "delete", required = false) Integer id)
        {
            List<Message> messages= messagesService.getAllMessages();
            model.addAttribute("messages", messages);

            if(principal != null) 
            {
                model.addAttribute("loggedInUser", principal.getName());
            }

            if(id != null) 
            {
                messagesService.deleteMessage(id);
                return "redirect:/boardroom";
            }

            return "boardroom";
        }

@RequestMapping("/createmessage")
    public String showCreateMessage(Model model,
                                    @RequestParam(value = "edit", required = false) Integer edit)
    {
        Message message = null;

        if(edit != null) 
        {
            message = messagesService.getUserMessageById(edit);
        }

        if(message == null)
        {
            message =new Message();
        }

        model.addAttribute("message", message);

        return "createmessage";
    }



@RequestMapping(value="/docreate", method=RequestMethod.POST)
    public String doCreate(Model model, @Validated(value=FormValidationGroup.class) 
                           @Valid Message message, 
                           BindingResult result, 
                           Principal principal,
                           @RequestParam(value = "edit", required = false) Integer edit)
    {
        if(result.hasErrors())
        {
            return "createmessage";
        }

        if(edit==null)
        {
            String username = principal.getName();
            message.getUser().setUsername(username);
        }
        else
        {
            message=messagesService.getUserMessageById(edit);
        }

        messagesService.saveOrUpdate(message);

        return "messagesaved";
    }

/createmessage.jsp

<sf:form method="POST" action="${pageContext.request.contextPath}/docreate" commandName="message">
    <table class="formtable">
        <tr><td class="label">Text:</td><td><sf:textarea class="control" path="text" name="text" rows="10" cols="30"></sf:textarea><br/><sf:errors path="text" cssClass="error"></sf:errors></td></tr>
        <tr><td></td><td><input class="controlButton" value="Save Message" type="submit"/></td></tr>
    </table>
</sf:form>

更新

MessagesService

@Secured({"ROLE_ADMIN", "ROLE_USER"})
    public void saveOrUpdate(Message message)
    {
        messagesDAO.saveOrUpdate(message);
    }

MessagesDAO

@Transactional
    public void saveOrUpdate(Message message)
    {
        session().saveOrUpdate(message);
    }

1 个答案:

答案 0 :(得分:3)

hibernate的

saveOrUpdate()工作原理:当传递具有标识符值的实例时,它将更新数据库中的记录。

如果传递的实例的标识符没有值或者说为null,那么它将在DB中执行insert记录。

因此,在您的情况下,传递的实例message没有其标识符的值,这就是为什么hibernate在DB上执行插入操作的原因。如果记录在DB中可用并设置为标识符字段,则必须获取其主键。

                                         OR

另一个原因可能是您没有将事务提交到DB,因此更改将写入DB。 (为此我需要看你的服务类)