I'm doing some ETL work, moving users and groups from an app-specific db to a share-able user/group/login facility.
Unfortunately some user's emails are duplicated in the source. I'm keeping a HashSet of all emails and user names. With each new incoming record I check the caches for the name or email (adding if not found). If I have a cache hit, since it could be a user already in the db prior to the transfer I'm reading, JPA-style the user by name or email (both are enforced to be unique).
However when I hit the second occurance of an email in the source, on which I have previously called persist(), the read from the db throws
javax.persistence.EntityExistsException: org.hibernate.exception.ConstraintViolationException: could not insert collection: [c.a.s.e.c.Group.users#101060]
java.sql.BatchUpdateException: Batch entry 13 insert into group_user_join (group_id, user_id) values (101060, 101699) was aborted.
as though hibernate is adding the read-in user into the group to which the user was added earlier.
User has
Code:
@ManyToMany(mappedBy="users", fetch = FetchType.LAZY)
private Collection<Group> groups;
and Group has
Code:
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name="group_user_join",
joinColumns={@JoinColumn(name="group_id")},
inverseJoinColumns={@JoinColumn(name="user_id")})
private Collection<User> users;
The lookup is
Code:
Query ueLookup = em.createQuery("select u from User u where userName = :uname or emailAddress = :mail");
ueLookup.setParameter("uname", username);
ueLookup.setParameter("mail", email);
try {
foundUser = (User)ueLookup.getSingleResult();
}
Does the setup look correct?
Am I diagnosing the exception correctly?
If so, any thoughts on how to get round the problem?
(I am catching the none-found and too-many exceptions)
Thanks.