当前位置: 首页 > 知识库问答 >
问题:

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

贺海
2023-03-14

Contact实体定义了与两个MySQL表中存在的email和nickname类型的实体集合的关系。

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

{
  "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
    }
  ]
}
{
  "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
    }
  ]
}
@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 =? 

问候你,伊恩。

共有1个答案

林龙野
2023-03-14

如果您不希望集合中有重复项,则应该在实体中使用set而不是collection

 类似资料:
  • 问题内容: 我希望将空结果集的总计设置为0。我尝试了以下方法: 结果: 子问题:上面的工作在Oracle中行不通吗? 问题答案: 在有关聚合函数的文档页面中: 应该注意的是,除了这些函数, 当没有选择任何行时 ,这些函数将 返回空值 。特别是,没有行返回空值,而不是预期的零值。必要时,该函数可用于将零替换为null。 所以,如果你想保证返回的值,适用于 结果 的,而不是它的参数: 至于Oracle

  • 我正在使用Spring Cache,其中我传入一个键集合,返回是一个实体列表。我想让缓存框架明白返回列表中的每个元素都将使用相应的代码进行缓存。目前,键似乎是整个列表,如果我在后续调用中缺少一个键,它将再次尝试重新加载整个集合。 另一种可能性是返回是一个映射,同样,我希望缓存足够智能,可以只查询以前从未查询过的项目,也可以用它的键缓存每个项目。 假设乡村类如下所示: 这在Spring Cache中

  • 我正在使用spring数据JPA存储库来调用存储过程。就好像在整个应用程序中,我们对存储过程有严格的依赖性一样,我必须使用非实体存储过程调用。以下是我选择的称呼方式: 它适用于存储过程返回单个结果集的所有情况。 但是它不适用于返回多个结果集的存储过程。它只返回第一个结果集,不给出任何错误。 在我们的项目中,我们有spring-boot-starter-data-jpa版本1.5.8和hiberna

  • 我有一个包含元素列表的实体,现在我想搜索这些元素的属性。这个约束应该是“与”连接的。请看这些简单的例子: 现在我想找到某个城市的家长,比如说“BigCity”,孩子们在学校“AwesomeSchool”,他们在六年级一班。我只想通过CriteriaBuilder获得搜索结果。 到目前为止,我得到了: 不幸的是,这里有两个问题:-看起来我无法在列表属性上调用-这将返回所有孩子在“AwesomeSch

  • 我有一个Spring批处理应用程序,需要从4个表中进行选择。问题是,我无法使用关系,将编写Enricher来选择完整数据。 目前我有几个问题: 是否可以以简单的方式从JpaRepository映射非实体(POJO)。我看到了的示例。我正在寻找自动映射(也许是JPA,而不是Spring Data)。我可以用结果精确地制作列名,但它不起作用。 将POJO标记为实体没问题,但有问题。实体需要。这对我来说

  • execute方法不仅可以执行单条查询语句,而且还可以执行多条查询语句,不同查询语句之间用分号(;)隔开。在给出例子之前,先使用如下SQL建立一个图书销售表t_booksale,并向其中插入三条记录。 建立t_booksale表 DROP TABLE IF EXISTS mydb.t_booksale; CREATE TABLE mydb.t_booksale ( id int(10)