QGA
QGA

Reputation: 3192

Hibernate save or update issue

I am facing an issue when I save an offer from the /createmessage page. I am using hibernate to save or delete it and it automatically elicits if the message should be updated or created (session().saveOrUpdate(message)). At the moment this creates a new message every time and does not update

Message Model

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

Messages Table

<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>

Controllers

@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>

UPDATE

MessagesService

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

MessagesDAO

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

Upvotes: 0

Views: 471

Answers (1)

Amogh
Amogh

Reputation: 4573

saveOrUpdate() of hibernate work as : When passed instance having value for identifier then it will update the record in DB.

If identifier of passed instance is not having value or say null then It will execute insert the record in DB.

So in your case passed instance message is not having value for its identifier that's why hibernate executing insert on DB. You have to fetch its primary key also in case if record is available in DB and set to identifier field.

                                         OR

Another reason may be you are not committing transaction to DB, so that changes will get written to DB. (For that I need to see you service class)

Upvotes: 3

Related Questions