The Contact entity defines relationships to two collections of entity of type email and nickname which exist in two MySQL tables.
My issue is that the result set this returns has duplicated email and nicknames.
{
"contactId": 1,
"givenName": "toast",
"middleName": "brown",
"familyName": "jam",
"dob": "2014-11-19",
"contactEmailAddress": [
{
"emailAddressId": 1,
"emailAddress": "[email protected]",
"contactId": 1
},
{
"emailAddressId": 1,
"emailAddress": "[email protected]",
"contactId": 1
},
{
"emailAddressId": 2,
"emailAddress": "[email protected]",
"contactId": 1
},
{
"emailAddressId": 2,
"emailAddress": "[email protected]",
"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
}
]
}
If I remove the ContactNickname collection from the Contact entity the result set is as follows.
{
"contactId": 1,
"givenName": "toast",
"middleName": "brown",
"familyName": "jam",
"dob": "2014-11-19",
"contactEmailAddress": [
{
"emailAddressId": 1,
"emailAddress": "[email protected]",
"contactId": 1
},
{
"emailAddressId": 2,
"emailAddress": "[email protected]",
"contactId": 1
}
]
}
I expected a distinct collection of email address and a distinct collection of nicknames but this is not the case. What am I doing incorrectly.
Using JPA I have mapped the the class as follows.
@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 is running the following when the duplication happens.
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 =?
Kind regards, Ian.
If you never want to have duplicates in your collection, you should use
Set
instead ofCollection
in your entity.