java - 具有多个集合的 JPA 实体结果集重复

标签 java hibernate jpa duplication

联系人实体定义了与存在于两个 MySQL 表中的电子邮件和昵称类型的两个实体集合的关系。

我的问题是返回的结果集包含重复的电子邮件和昵称。

{
  "contactId": 1,
  "givenName": "toast",
  "middleName": "brown",
  "familyName": "jam",
  "dob": "2014-11-19",
  "contactEmailAddress": [
    {
      "emailAddressId": 1,
      "emailAddress": "donald.duck@disney.com",
      "contactId": 1
    },
    {
      "emailAddressId": 1,
      "emailAddress": "donald.duck@disney.com",
      "contactId": 1
    },
    {
      "emailAddressId": 2,
      "emailAddress": "mickey.mouse@disney.com",
      "contactId": 1
    },
    {
      "emailAddressId": 2,
      "emailAddress": "mickey.mouse@disney.com",
      "contactId": 1
    }
  ],
  "contactNickname": [
    {
      "contactNicknameId": 1,
      "nickname": "mm",
      "contactId": 1
    },
    {
      "contactNicknameId": 2,
      "nickname": "mouse",
      "contactId": 1
    },
    {
      "contactNicknameId": 1,
      "nickname": "mm",
      "contactId": 1
    },
    {
      "contactNicknameId": 2,
      "nickname": "mouse",
      "contactId": 1
    }
  ]
}

如果我从联系人实体中删除 ContactNickname 集合,结果集如下。

{
  "contactId": 1,
  "givenName": "toast",
  "middleName": "brown",
  "familyName": "jam",
  "dob": "2014-11-19",
  "contactEmailAddress": [
    {
      "emailAddressId": 1,
      "emailAddress": "donald.duck@disney.com",
      "contactId": 1
    },
    {
      "emailAddressId": 2,
      "emailAddress": "mickey.mouse@disney.com",
      "contactId": 1
    }
  ]
}

我期望有一组不同的电子邮件地址和一组不同的昵称,但事实并非如此。我做错了什么。

使用 JPA,我已映射该类,如下所示。

@Entity
@Table(name="contact")
public class Contact implements Serializable {    
    @OneToMany(fetch=FetchType.EAGER)
    @JoinColumn(name="contact_id")
    private Collection<ContactEmailAddress> contactEmailAddress;

    @OneToMany(fetch=FetchType.EAGER)
    @JoinColumn(name="contact_id")
    private Collection<ContactNickname> contactNickname;

    public Collection<ContactEmailAddress> getContactEmailAddress(){
        return this.contactEmailAddress;
    }

    public void setContactEmailAddress(Collection<ContactEmailAddress> contactEmailAddress){        
        this.contactEmailAddress=contactEmailAddress;
    }

    public Collection<ContactNickname> getContactNickname(){
        return this.contactNickname;
    }

    public void setContactNickname(final Collection<ContactNickname> contactNickname){
        this.contactNickname=contactNickname;
    }    
}
@Entity
@Table(name="contact_email_address")
public class ContactEmailAddress implements Serializable {   
    @Id
    @GeneratedValue
    @Column(name="email_address_id")
    private int emailAddressId;

    @Column(name="email_address")
    private String emailAddress;

    @Column(name="contact_id")
    private int contactId;

  public void setContactId(int contactId){
        this.contactId=contactId;
    }

    public int getContactId(){
        return this.contactId;
    }.

   public int getEmailAddressId(){
        return emailAddressId;
    }

    public void setEmailAddressId(final int emailAddressId){
        this.emailAddressId=emailAddressId;
    }

    public String getEmailAddress(){
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress){
        this.emailAddress=emailAddress;
    }
}
@Entity
@Table(name="contact_nickname")
public class ContactNickname implements Serializable {
    @Id
    @GeneratedValue
    @Column(name="contact_nickname_id")
    private int contactNicknameId;

    @Column(name="nickname")
    private String nickname;

    @Column(name="contact_id")
    private int contactId; 

    public int getContactNicknameId(){
        return contactNicknameId;
    }

    public void setContactNicknameId(final int contactNicknameId){
        this.contactNicknameId=contactNicknameId;
    }

    public String getNickname(){
        return this.nickname;
    }

    public void setNickname(String nickname){
        this.nickname=nickname;
    }    

    public void setContactId(int contactId){
        this.contactId=contactId;
    }

    public int getContactId(){
        return this.contactId;
    }
}

当发生重复时,Hibernate 正在运行以下命令。

SELECT contact0_.contact_id             AS contact_1_0_0_, 
       contact0_.dob                    AS dob2_0_0_, 
       contact0_.family_name            AS family_n3_0_0_, 
       contact0_.given_name             AS given_na4_0_0_, 
       contact0_.middle_name            AS middle_n5_0_0_, 
       contactema1_.contact_id          AS contact_2_0_1_, 
       contactema1_.email_address_id    AS email_ad1_1_1_, 
       contactema1_.email_address_id    AS email_ad1_1_2_, 
       contactema1_.contact_id          AS contact_2_1_2_, 
       contactema1_.email_address       AS email_ad3_1_2_, 
       contactnic2_.contact_id          AS contact_2_0_3_, 
       contactnic2_.contact_nickname_id AS contact_1_3_3_, 
       contactnic2_.contact_nickname_id AS contact_1_3_4_, 
       contactnic2_.contact_id          AS contact_2_3_4_, 
       contactnic2_.nickname            AS nickname3_3_4_ 
FROM   contact contact0_ 
       LEFT OUTER JOIN contact_email_address contactema1_ 
                    ON contact0_.contact_id = contactema1_.contact_id 
       LEFT OUTER JOIN contact_nickname contactnic2_ 
                    ON contact0_.contact_id = contactnic2_.contact_id 
WHERE  contact0_.contact_id =? 

亲切的问候, 伊恩.

最佳答案

如果您不想在集合中出现重复项,则应在实体中使用 Set 而不是 Collection

关于java - 具有多个集合的 JPA 实体结果集重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27041945/

相关文章:

java - 为什么我的 ANTLR 构建 Ant 任务失败并返回 "Unable to determine generated class"?

java - 在 Java 中,哪个重载会被选为 null?

java - 在模型类中使用 javafx.beans 属性

mysql - 在控制台中从 Spring JPA 查询与原始 SQL 获取不同的结果

java - 如何使用 JPA GROUP BY 获取 SELECT 值和 COUNT 值

java - JPA 与 Google Cloud SQL "NoClassDefFoundError: java.util.prefs.Preferences is a restricted class"

java - 如何添加两个对象?

java - 如何检测我的Android应用程序是否已连接到Chromecast音频或视频?

java - JPQL 与字符串函数不同

java - 我们如何告诉 Hibernate 将标识符属性设置为可选