I have a unidirectional one-to-many association between an entity 'Media' to an entity 'Comment'.
My problem is the classic concurrency 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.
Environment:
Hibernate 3.2.6
Jboss 4.2.2.GA
Jboss Seam 2.0.2.GA
Code:
@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
Code:
@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 MEDIA2MEDIA_COMMENTS 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
Code:
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 (?, ?)
thanks.