5 Replies Latest reply on May 28, 2008 11:21 AM by Fredrik Forsberg

    collection concurrency problem

    Fredrik Forsberg Newbie

      I 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 (?, ?)