【发布时间】:2015-01-18 10:52:07
【问题描述】:
Contact 实体定义了与两个 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
}
]
}
如果我从 Contact 实体中删除 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 =?
亲切的问候, 伊恩。
【问题讨论】:
-
基本上你正在尝试做一个单向的oneToMany映射;您缺少一个“referencedColumnName”属性,正如这个非常相似的问题中所解释的那样:stackoverflow.com/questions/12038380/…
-
@Gimby 设置 referencedColumnName="contact_id" 时我仍然得到相同的结果集
-
嗯。只是为了排除可能性:当您从集合中删除 EAGER 获取时,是否会发生任何变化?
-
@Gimby 我目前得到 org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role... Contact.contactEmailAddress,无法初始化代理 - 没有会话
-
@Gimby 在将两个集合都设置为惰性然后在事务关闭之前对它们都调用 size() 之后,Jackson 生成了没有实体重复的正确 JSON。所以一切都很好。为什么急切加载集合会生成重复。
标签: java hibernate jpa duplication