我確信這個問題之前已經被問過了,但我似乎無法找到答案。我正在使用Hibernate 4.0做一個基本的關係。我有一個Person對象可以包含可能的地址(是的,從另一個網站得到的代碼認爲它會工作,但事實並非如此)。我想要使用連接表。我覺得我已經嘗試了所有可能的組合,但不斷提出相同的錯誤:「對於鍵1,重複輸入」1-3「。基本上,當我在設置雙方關係(人員/地址)後嘗試提交事務時發生Hibernate錯誤。很明顯,它試圖插入相同的記錄兩次,這是連接表上不允許的,因爲personId/addressId組合應該只出現一次。任何幫助將不勝感激,一個有效的Junit測試也許。在下面我手動插入一個人和三個地址,前兩個已經與該人有關。休眠一對多連接表 - 重複插入
1)我是否必須明確設置雙方的關係(人員和地址)?似乎不正確,因爲其他對象之一會不同步。 2)爲什麼這個工作正常,如果我使用List而不是Set?
單元測試:
@Test
public void tryAgain(){
Person p = em.find(Person.class, 1);<br>
Address a = em.find(Address.class, 1);<br>
Address b= em.find(Address.class,2);<br>
Address c= em.find(Address.class, 3);<br>
em.getTransaction().begin();<br>
p.addresses.add(c);<br>
c.person=p;<br>
em.getTransaction().commit();<br>
assertTrue(p.addresses.size()==3);<br>
}
JUnit的堆棧跟蹤
Hibernate: select person0_.personId as personId3_0_ from PERSON person0_ where person0_.personId=?
<br>Hibernate: select address0_.addressId as addressId6_1_, address0_1_.personId as personId7_1_, person1_.personId as personId3_0_ from ADDRESS address0_ left outer join PersonAddress address0_1_ on address0_.addressId=address0_1_.addressId left outer join PERSON person1_ on address0_1_.personId=person1_.personId where address0_.addressId=?
<br>Hibernate: select address0_.addressId as addressId6_1_, address0_1_.personId as personId7_1_, person1_.personId as personId3_0_ from ADDRESS address0_ left outer join PersonAddress address0_1_ on address0_.addressId=address0_1_.addressId left outer join PERSON person1_ on address0_1_.personId=person1_.personId where address0_.addressId=?
<br>Hibernate: select address0_.addressId as addressId6_1_, address0_1_.personId as personId7_1_, person1_.personId as personId3_0_ from ADDRESS address0_ left outer join PersonAddress address0_1_ on address0_.addressId=address0_1_.addressId left outer join PERSON person1_ on address0_1_.personId=person1_.personId where address0_.addressId=?
<br>Hibernate: select addresses0_.personId as personId3_2_, addresses0_.addressId as addressId2_, address1_.addressId as addressId6_0_, address1_1_.personId as personId7_0_, person2_.personId as personId3_1_ from PersonAddress addresses0_ inner join ADDRESS address1_ on addresses0_.addressId=address1_.addressId left outer join PersonAddress address1_1_ on address1_.addressId=address1_1_.addressId left outer join PERSON person2_ on address1_1_.personId=person2_.personId where addresses0_.personId=?
<b>Hibernate: insert into PersonAddress (personId, addressId) values (?, ?)
<br>Hibernate: insert into PersonAddress (personId, addressId) values (?, ?)</b>
<br>Dec 26, 2011 10:40:27 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
警告:SQL錯誤:1062 SQLSTATE:23000
2011年12月26日10點四十分27秒PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions 錯誤:對於密鑰1重複條目'1-3'
代碼
@Entity<br>
@Table(name="PERSON")<br>
public class Person {<br>
@Id<br>
@GeneratedValue(strategy = GenerationType.AUTO)<br>
@Column(name = "personId")<br>
public int id;<br>
@OneToMany()<br>
@JoinTable(name = "PersonAddress",
joinColumns = {
@JoinColumn(name="personId", unique = true)},
inverseJoinColumns = {
@JoinColumn(name="addressId")})<br>
public Set<Address> addresses = new HashSet<Address>();<br>
}
@Entity
@Table(name = "ADDRESS")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "addressId")
public int id;
@ManyToOne(optional=true,cascade={CascadeType.ALL})
@JoinTable(name = "PersonAddress",
joinColumns = {@JoinColumn(name="addressId",insertable=false,updatable=true)},
inverseJoinColumns = {
@JoinColumn(name="personId")
})
public Person person;
}
這種關係的存在方式是一個人可以有多個地址,並且一個地址可以在沒有人的情況下存在(地址可以是空的)。爲了使用mappedBy =「person」屬性,我必須在Address表中有parentId鍵。我不想要這個,因爲地址只能屬於一個人。連接表允許多個人與地址相關聯。此外,這些字段爲了簡化而不公開,不準確。 – user1116536 2011-12-27 13:12:38
如果一個人有幾個地址,並且一個地址可能屬於多個人,那麼您沒有一對多關聯,而是多對多關聯。 Address實體應該有一個人員集合,而不是Person字段。無論您是否使用連接表,mappedBy都可以使用。它只是意味着:另一方有映射信息。但是,嘿,如果您不相信回答者(並且在hibernate標記中有538個選票,在JPA標記中有258個),爲什麼要問問題? – 2011-12-27 13:27:11