在我的应用程序中,我有以下实体:
@Entity
public class Commentable implements Serializable {
...
@ElementCollection(targetClass = String.class)
protected Set<String> likers = new HashSet<String>();
...
}
每当用户单击“赞”按钮时,我会将他的用户名添加到上面Set
,以确保他永远不会两次赞同一个帖子。但是,当我查看数据库时,我看到多次出现相同的用户名。
如果我打电话likers.size()
,我仍然可以从Set
. 然而,以下查询将始终返回更大的数字:
Query q1 = em.createQuery("SELECT COUNT(L) FROM Commentable C JOIN C.likers L WHERE C.id = :id");
q1.setParameter("id", commentableID);
long numberOfLikes = (Long) q1.getSingleResult();
System.out.println("HERE " + numberOfLikes);
该数据库包含如下条目:
# | Commentable_ID | LIKERS
1 | 1801 | Mr.James
2 | 1801 | Mr.James
3 | 1801 | Mr.James
更新 1:
正如 JMelnik 所建议的,我尝试加入唯一约束:
@Entity
public class Commentable implements Serializable {
...
@ElementCollection(targetClass = String.class)
@Column(unique=true)
protected Set<String> likers = new HashSet<String>();
public void addLiker(String liker) {
this.likers.add(liker);
}
...
}
当我第二次单击“赞”按钮时,GlassFish 向我抛出了以下异常:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'jamesboyz' for key 'LIKERS'
Error Code: 1062
Call: INSERT INTO Commentable_LIKERS (Commentable_ID, LIKERS) VALUES (?, ?)
bind => [2 parameters bound]
Query: DataModifyQuery(sql="INSERT INTO Commentable_LIKERS (Commentable_ID, LIKERS) VALUES (?, ?)")
...
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'jamesboyz' for key 'LIKERS'
更新 2:
在我的一个中SessionBean
,我有以下记录喜欢的方法:
@Override
public int like(long commentableID, String liker) {
Commentable c = em.find(Commentable.class, commentableID);
if (c == null) return STATUS_NOT_FOUND;
else {
c.addLiker(liker);
return STATUS_SUCCESSFUL;
}
}
如果您能告诉我为什么会发生这种情况以及如何避免数据库中的重复条目,我将不胜感激。
此致,
詹姆斯·特兰