collection concurrency problem
fredf May 27, 2008 4:10 PMI have a unidirectional one-to-many association between an entity 'Media' to an entity 'Comment'.
My usecase is similar to the commenting in the seam wiki example. The difference is that the relationship between
Document and Comment in the wiki example is bidirectional.
My problem is the classic concurreny problem. When two users adds a comment each to a media, User A's comment gets overwritten by User B.
This is the store comment logic. It like a transaction isolation level problem but on a table level instead of one particular table row.
@Name("detailedMediaForm") @Scope(ScopeType.PAGE) public class DetailedMediaForm implements Serializable { private java.lang.String comment; private Media media; private Long mediaId; private Collection<MediaComment> mediaComments; // injecting daos @Create public void initMedia() { Media loadedMedia = mediaDAO.findById(mediaId); } public String postComment() { media = mediaDAO.update(media); // does a merge refreshComments(); MediaComment mediaComment = new MediaComment(comment); media.getMediaComments().add(mediaComment); messageDAO.create(mediaComment); mediaDAO.update(media); refreshComments(); return "success"; } public Media getMedia() { return media; } public void refreshComments(){ mediaComments = mediaDAO.findMediaCommentsByMediaId(mediaId); } // plumbing methods // getters and setters }
This is the annotation for the comments colleciton in media entity
@javax.persistence.OneToMany(cascade = {javax.persistence.CascadeType.ALL}, fetch = javax.persistence.FetchType.EAGER) @javax.persistence.JoinTable ( name = "MEDIA2MEDIA_COMMENTS", joinColumns = {@javax.persistence.JoinColumn(name = "MEDIA_ID_FK", referencedColumnName = "ID")}, inverseJoinColumns = {@javax.persistence.JoinColumn(name = "MEDIA_COMMENTS_ID_FK", referencedColumnName = "ID")} )
The message is persisted in the MESSAGE table but the rows in the jointable MEDIA2MEDIACOMMENTS between media and comment gets deleted when the link is persisted.
Why does Hibernate delete the links before inserting the new link to my persisted comment?
hibernate output
15:14:55,078 INFO [STDOUT] Hibernate: /* insert storage.MediaComment */ insert into MESSAGE (ALLOW_COMMENTS, BODY, CONTENT_PROVIDER_ACCOUNT_FK, DATE, TITLE, TYPE) values (?, ?, ?, ?, ?, 'M') 15:14:55,218 INFO [STDOUT] Hibernate: /* delete collection convert.frontend.storage.Media.mediaComments */ delete from MEDIA2MEDIA_COMMENTS where MEDIA_ID_FK=? 15:14:55,218 INFO [STDOUT] Hibernate: /* insert collection row convert.frontend.storage.Media.mediaComments */ insert into MEDIA2MEDIA_COMMENTS (MEDIA_ID_FK, MEDIA_COMMENTS_ID_FK) values (?, ?) 15:14:55,218 INFO [STDOUT] Hibernate: /* insert collection row convert.frontend.storage.Media.mediaComments */ insert into MEDIA2MEDIA_COMMENTS (MEDIA_ID_FK, MEDIA_COMMENTS_ID_FK) values (?, ?)