【问题标题】:Database contains duplicate entries from a Set<String>数据库包含来自 Set<String> 的重复条目
【发布时间】:2012-06-01 01:06:11
【问题描述】:

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

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

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

最好的问候,

詹姆斯·特兰

【问题讨论】:

  • 对于 same 可评论的用户名多次出现?请显示数据库中的一些示例输出。
  • 尝试在@Column 和数据库列(如果不是自动生成的表)上设置唯一约束。然后从数据库中删除重复的条目,然后尝试一些 testdrive 或 smth。
  • @Perception 我刚刚更新了我的帖子,你需要这个吗?
  • @JMelnik 请看我上面的更新。
  • 请提供您将项目添加到喜欢者集中的代码并保留它。

标签: java jpa entity set


【解决方案1】:

我的猜测是,如果您将 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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-20
    • 2014-04-06
    • 2017-05-08
    • 2015-08-09
    • 2019-11-29
    • 1970-01-01
    • 2012-10-16
    • 2015-05-21
    相关资源
    最近更新 更多