0

在我的应用程序中,我有以下实体:

@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;
    }
}

如果您能告诉我为什么会发生这种情况以及如何避免数据库中的重复条目,我将不胜感激。

此致,

詹姆斯·特兰

4

1 回答 1

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);
    }
}
于 2012-05-28T13:38:45.617 回答