Hibernate 學習心得1: 多對多關係中,中間表無法插入資料。
阿新 • • 發佈:2019-02-01
Hibernate 學習心得之一 多對多關係中,中間表無法插入資料。
最近學習 spring4+hibernate4,學習中遇到了很多坑。在這裡我來說說我遇到的坑,這裡就不介紹如何spring如何整合hibernate。目前學習過程中,我遇到的兩個問題1.為何在hibernate多對多關係中,無法插入中間表的資料2.為何配置了spring事務註解。可是在使用@transactional Hibernate儲存資料還是沒能正常執行事務。先貼出兩個類,Person 和 Song,人物類和歌曲類。get,set方法等略掉Person 和 Song 存在多對多的關係1.第一個問題,為何在hibernate多對多關係中,無法插入中間表的資料一開始使用這種方法儲存資料。@Entity @Table(name = "Person") public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "name") private String name; //身高 單位cm @Column(name = "height") private float height; //體重 單位kg @Column(name = "weight") private float weight; //性別 @Column(name = "gender") private boolean gender; //年齡 @Column(name = "age") private int age; @ManyToMany() @Cascade(value = {CascadeType.SAVE_UPDATE}) @JoinTable(name = "Song_Person", joinColumns = {@JoinColumn(name = "personId", referencedColumnName="id")}, inverseJoinColumns = {@JoinColumn(name = "songId", referencedColumnName="id")}) private Set<Song> songs = new HashSet<Song>(); } @Entity @Table(name = "Song") public class Song { @Id @GeneratedValue private int id; @Column(name = "songName") private String songName; //演唱者 @ManyToMany() @Cascade(value = {CascadeType.SAVE_UPDATE}) @JoinTable(name = "Song_Person", //本表與中間表的外來鍵對應關係 joinColumns = {@JoinColumn(name = "songId", referencedColumnName="id")}, //另一張表與中間表的外來鍵的對應關係 inverseJoinColumns = {@JoinColumn (name = "personId", referencedColumnName="id")}) private Set<Person> singers = new HashSet<Person>(); }
save() 方法 使用 sessionFactory.openSession() 儲存資料,結果死活中間表儲存不了資料。也沒有報錯,一開始的解決方法是看註解有沒有用錯。後來查資料發現並沒有用錯。經過各種測試後發現 需要呼叫事務開啟和提交。改成:public Integer savePerson(String songName){ Song song = new Song(); song.setSongName(songName); Person person = new Person("張國榮", 180.0F, 56.8F, true, 40); person.getSongs().add(song); personDao.save(person); } public Integer save(Person entity) { int id = (Integer) sessionFactory.openSession().save(entity); return id; }
2.第二個問題,配置了spring事務註解,可是在使用@transactional Hibernate儲存資料還是沒能正常執行事務首先新增Spring配置public Integer save(Person entity) { //開啟一次事物 Session session = sessionFactory.openSession(); Transaction tran = session .beginTransaction(); int id = (Integer) session .save(entity); tran.commit(); return id; }
<!-- 事物管理器配置 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 註解實現事務 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
然後我就開始使用@Transactional註解@Transactional
public Integer save(Person entity) {
Session session = sessionFactory.openSession();
int id = (Integer) session .save(entity);
return id;
}
可是結果發現,使用了這個註解,之後,反而又再一次不能插入中間表資料了。最後解決辦法是使用sessionFactory.getCurrentSession(),而不是使用sessionFactory.openSession(),具體原理,請大家谷歌查。這裡就不介紹了。@Transactional
public Integer save(Person entity) {
Session session = sessionFactory.getCurrentSession();
int id = (Integer) session .save(entity);
return id;
}
改成這樣就可以順利地執行事務,中間表資料也就自然有了。