user2031269
user2031269

Reputation: 15

Spring MVC and Hibernate - How to save data in two tables when persisting an object?

I want to accomplish the following:

A user can post a message, with a title and a description. He can also leave either his email address, his phone number, or both.

I want to store the info about his message in one table, with the columns id, userId, title and description. I want to store the info about his contact info in another table, with the columns id, messageId, phoneNumber and email. I want to be able to list the messages. For each message, I also want to print the phone number and the email address.

I want to store the contact info in a different table for different reasons, I am not able to store them with the message, in the message table.

I don't know what is the best way to accomplish this, especially knowing that I want to be able to retrieve a contact info with the ID of a Message.

I have tried multiple ways, with @OneToOne, @JoinColumn or @SecondaryTable but cannot get this to work.

Here is what I have right now:

Message class:

@Entity
@Table(name="messages")
public class Message implements Serializable {
    private int idMessage;
    private int userId;
    private String title;
    private String description;
    private Contact contact;

    @Id
    @GeneratedValue
    @Column(name="idMessage")
    public int getId() {
        return idMessage;
    }

    public void setId(int id) {
        this.id = id;    
    }

    @Column(name="userId", nullable=false)
    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }


    @Column(name="title", nullable=false)
    public int getTitle() {
        return title;
    }

    public void setTitle(int title) {
        this.title = title;
    }


    @Column(name="description", nullable=false)
    public int getDescription() {
        return userId;
    }

    public void setDescription(int description) {
        this.description = description;
    }

    @OneToOne(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
    @JoinColumn(name="contactId", nullable=false)
    public Contact getContact() {
        return contact;
    }

    public void setContact(Contact contact) {
        this.contact = contact;
    }
}

Now, here is my contact class: Edit: I did add the attribute messageId in the Contact class. I also added the column in the Contact table and added a foreign key pointing to the id column of the Messages table. @Entity @Table(name="contacts") public class Contact {

    private String id;
    private int messageId;
    private Message message;
    private String phoneNumber;
    private String email;

    public Contact(Message message, String phoneNumber, String email) {
        this.message= message;
        this.phoneNumber = phoneNumber;
        this.email = email;
    }

    @Id
    @GeneratedValue
    @Column(name="ID")
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "contact")
    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }

    @Column(name="phoneNumber", nullable=true)
    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Column(name="email", nullable=true)
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

}

Some of my JSP code, please note that I did put contact.email and contact.phoneNumber in the path attribute for email and phone number fields:

<form:form method="post" commandName="ad">
            <table width="95%" bgcolor="f8f8ff" border="0" cellspacing="0"
                cellpadding="5">

                <tr>
                    <td align="right" width="20%">Title *</td>
                    <td width="20%"><form:input size="64" path="title" class="input-xxlarge"/></td>
                    <td width="60%"><form:errors path="title" cssClass="error" /></td>
                </tr>
                <tr>
                    <td align="right" width="20%">Description *</td>
                    <td width="20%">
                        <%-- <form:input path="description" /> --%> <textarea rows="3"></textarea>
                    </td>
                    <td width="60%"><form:errors path="description"
                            cssClass="error" /></td>
                </tr>
                <tr>
                    <td align="right" width="20%">Phone Number *</td>
                    <td width="20%"><form:input path="contact.phoneNumber" /></td>
                    <td width="60%"><form:errors path="contact.phoneNumber" cssClass="error" /></td>
                </tr>
                <tr>
                    <td align="right" width="20%">Email *</td>
                    <td width="20%"><form:input path="contact.email" /></td>
                    <td width="60%"><form:errors path="contact.email" cssClass="error" /></td>
                </tr>
            </table>

Upvotes: 0

Views: 4435

Answers (1)

Bozho
Bozho

Reputation: 597106

@OneToOne(cascade=CascadeType.ALL)
private Contact contact;

This means that:

  • for each Message there is exactly one Contact (and one contact is used by only one message)
  • whenever you perform a save, update or delete operation on a Message, that operation is cascaded to the contact table.

Upvotes: 1

Related Questions