1

My entities representing a one-to-many:

@Entity
@Table(name = "Users")
public class User {
    @Id
    @GeneratedValue
    private int id = -1;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<SignIn> signIns;
}

@Entity
@Table(name = "SignIns")
public class SignIn {
    @Id
    @GeneratedValue
    private int id;
    @ManyToOne
    private User user;

    public SignIn(User user) {
        this.user = user;
    }
}

When I persist a User and then persist a SignIn with the created User, everything works fine (each table will have 1 row). When I reuse the created User to persist another sign in, the first sign in row gets replaced by the new sign in.

The code that persists:

User user = new User();
persist(user);
SignIn signIn = new SignIn(user);
SignIn signIn2 = new SignIn(user);
persist(signIn);
persist(signIn2);

private void persist(Object entity) {
        EntityManager em = entityManagerFactory.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.merge(entity);
            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            em.close();
        }
    }

What did I overlook?

AndrewBourgeois
  • 2,634
  • 7
  • 41
  • 58
  • 1
    How are you updating the SignIn in your code? – smk Oct 23 '12 at 17:04
  • I'm adding a new SignIn with the same User. To persist the new SignIn, I use http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#persist(java.lang.Object), just like I did for the User entity and the first SignIn. – AndrewBourgeois Oct 23 '12 at 17:07
  • I think you need to retrieve entire list. And add it to that list. Unless I'm missing something – smk Oct 23 '12 at 17:30
  • It's the CascadeType.ALL that causes the issue. Without it, the entries are correctly added. I want to delete the sign ins when I delete the user (I also just tried CascadeType.DELETE). – AndrewBourgeois Oct 23 '12 at 17:34
  • Show us the code used to create a new SignIn. – JB Nizet Oct 23 '12 at 17:53
  • Done. Do you have any idea? It works when I remove the CascadeType, but I need it to automatically remove the SignIns when the User gets deleted. – AndrewBourgeois Oct 23 '12 at 19:02
  • What happens if you use `em.persist(entity)` instead of `em.merge(entity)`? Just a guess, but [JPA EntityManager: Why use persist() over merge()?](http://stackoverflow.com/q/1069992/3340) is what led me to that. – Jacob Schoen Oct 23 '12 at 20:00
  • Did you try adding the `SignIn` objects to the `User` and saving the `User` instead? – Jacob Schoen Oct 23 '12 at 20:14

1 Answers1

0

I had to set the SignIn on the inverse side too (User in my case).

So:
- create a sign in
- merge it
- add it the the User
- merge the User

AndrewBourgeois
  • 2,634
  • 7
  • 41
  • 58