在我的申请中,我有以下实体:
@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;
}
}
如果您能告诉我为什么会发生这种情况以及如何避免数据库中的重复条目,我将非常感激。
致以最诚挚的问候,
James Tran
答案 0 :(得分:0)
我的猜测是,如果你将addLiker方法更改为,
public void addLiker(String liker) {
this.likers.size();
this.likers.add(liker);
}
然后它会起作用。我记得这是一个问题,但认为它是固定的。你能试试2.4里程碑版本吗?否则记录一个错误,或找到现有的错误并投票。
您还应该能够修复它使关系EAGER,或在实体中使用@ChangeTracking(DEFERRED)。 你也可以用,
public void addLiker(String liker) {
if (!this.likers.contains(liker)) {
this.likers.add(liker);
}
}