雙向一對一的實例我已經上傳到GitHub,entrance項目上了,感興趣的可以下載下來跑跑,這里講兩個在運行過程中遇到的問題。
問題一:上一篇博客的最后我留下了問題。一對一關聯查詢注解@OneToOne的實例詳解
問題點:文章的最后,單向一對一程序在執行save語句的時候,分別執行了下面的語句:
Hibernate: select person0_.id as id1_2_1_, person0_.name as name2_2_1_, person0_.pet_id as pet_id3_2_1_, pet1_.id as id1_3_0_, pet1_.pet_class as pet_clas2_3_0_, pet1_.pet_name as pet_name3_3_0_ from person person0_ inner join pet pet1_ on person0_.pet_id=pet1_.id where person0_.id=?
Hibernate: insert into pet (pet_class, pet_name) values (?, ?)
Hibernate: insert into person (name, pet_id) values (?, ?)
Hibernate: insert into pet (pet_class, pet_name) values (?, ?)
Hibernate: update person set name=?, pet_id=? where id=?
這里我感覺很奇怪的地方就是執行了內連接,所以導致都沒有查到。
再看看雙向一對一執行的語句:
Hibernate: select husband0_.hid as hid1_1_1_, husband0_.hid_card as hid_card2_1_1_, husband0_.hname as hname3_1_1_, husband0_.w_id as w_id4_1_1_, wife1_.wid as wid1_6_0_, wife1_.wid_card as wid_card2_6_0_, wife1_.wname as wname3_6_0_ from husband husband0_ left outer join wife wife1_ on husband0_.w_id=wife1_.wid where husband0_.hid=?
Hibernate: insert into wife (wid_card, wname) values (?, ?)
Hibernate: insert into wife (wid_card, wname) values (?, ?)
Hibernate: update husband set hid_card=?, hname=?, w_id=? where hid=?
Hibernate: update husband set hid_card=?, hname=?, w_id=? where hid=?
雙向一對一連接的話第一句執行的是左連接,所以能查到數據,這樣就能直接更新了。
問題二:異常:在使用fastJson作為工具,將數據庫查到的數據轉換成fastJson輸出,拋出了:java.lang.StackOverflowError: null
這個異常就是堆棧溢出,可以很明顯的看出來,是因為husband對象與wife之前嵌套,在序列化的時候出現了這個異常。網上搜了一些,大多是List集合的嵌套,從中找到些蛛絲馬跡。解決的方法:
方法一:把wife中husband的屬性不序列化,加上屬性transient,加上序列屬性serialVersionUID
private static final long serialVersionUID = 8091602122698339709L; @Id // id自動生成 @GeneratedValue @Column(name = "wid") private Long wid; @Column(name = "wname") private String wname; @Column(name = "wid_card") private String widCard; @OneToOne(mappedBy = "wife",cascade=CascadeType.ALL) @JsonBackReference private transient Husband husband;
方法二:重新字節寫toString方法,不要使用系統自己生成的(這里也有技巧)。
husband.toString()
@Override public String toString() { return "{\"hid\":\"" + hid + "\",\"hname\":\"" + hname + "\",\"hidCard\":\"" + hidCard + "\",\"wife\":" + wife + "} "; }
wife.toString()
@Override public String toString() { return "{\"wid\":\"" + wid + "\",\"wname\":\"" + wname + "\",\"widCard\":\"" + widCard + "\"} "; }
我的代碼中采用了第二種方法。