3

I'm learning jpa and decided to do a basic webapp where a User can post Messages, so a user have many messages. The problem is that when I add a message to the User's messages collection, I get duplicated entries in the Message table. (note I have two tables with the owner Id on Message, there is no join table).

This is the conversation:

First message -> Larry says: Hello John

Second message -> Larry says: Are you there?

Third Message -> John says: Yep

Fourth Message -> Larry says: ok

Fifth Message -> John says: fine

This is what I get in the screen:

Larry: Hello John

Larry Hello John

Larry: Are you there?

John: Yep

Larry: Hello John

Larry: Are you there?

Larry: ok

John: Yep

John: fine

The table content is:

+----+----------------+----------+
| id | message        | owner_id |
+----+----------------+----------+
|  1 | Hello John     |     NULL | <- Why the NULL fields?
|  2 | Hello John     |     NULL |
|  3 | Are you there? |     NULL |
|  4 | Yep            |     NULL |
|  5 | Hello John     |        1 |
|  6 | Are you there? |        1 |
|  7 | ok             |        1 |
|  8 | Yep            |        2 |
|  9 | fine           |        2 |
+----+----------------+----------+

These are the classes I have and its mappings.

@Entity

public class User implements Serializable {

    @Id
    @GeneratedValue
    private Long id;
    private String username;
    private String password;

    @OneToMany (fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name="owner_id")
    private List<Message> messages; ...and all of its corresponding getters and setters

@Entity
public class Message implements Serializable {

    @Id
    @GeneratedValue
    private Long id;
    private String message;

    @ManyToOne
    private User owner; //...and all of its corresponding getters and setters

This is the relevant jsp scriptlet section which saves the user:

User user = (User)session.getAttribute("user");
user.getMessages().add(new Message(request.getParameter("message")));

FactoryDAO.getInstance().getUserDAO().update(user);

update(user) method:

public void update(User user) {
    initEntityManager(); <- method in the superclass which initializes the entityManager
    tx.begin();
    entityManager.merge(user);
    entityManager.flush();
    tx.commit();
    closeEntityManager();
}

Can you help me to find out what is wrong here? Thanks!

z-index
  • 409
  • 8
  • 14

2 Answers2

1

It might have something to do with the way you're creating new User objects (not shown in your code).

Other than that, a couple of things you could try:

  1. Use persist and not merge in the update method
  2. Use a Set instead of a List for storing messages
  3. Be sure to override equals and hashCode in both of your entities
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Hello Oscar, I use merge because I close the entityManager when I get a user in the login page and after storing it into the session. I tried Set as you suggested but I still get the same problem. I'm checking Johannes Brodwall's response about hashset on orm's http://stackoverflow.com/questions/27581/overriding-equals-and-hashcode-in-java Thanks for your response! – z-index Nov 19 '11 at 22:04
0

I fix the problem doing as follows:

<%
  User user = (User)session.getAttribute("user");
  Message message = new Message(request.getParameter("message"));
  message.setOwner(user);
  FactoryDAO.getInstance().getMessageDAO().update(message);
%>

I have set a owner to a message instead of a message to a user. I still don't understand why my first version didn't work as I expected.

z-index
  • 409
  • 8
  • 14