[英]Hibernate dropping session while looping on a collection
我遇到了這個異常LazyInitializationException: failed to lazily initialize a collection of roles, could not initialize proxy - no Session
在循環MyTable
集合時LazyInitializationException: failed to lazily initialize a collection of roles, could not initialize proxy - no Session
。 例如:
@Entity
@Table(name = "MY_TABLE")
public class MyTable {
@Id
private String id;
@OneToMany
@JoinColumn(
name = "key", referencedColumnName = "key_from_other_table",
updatable = false, insertable = false
)
private List<OtherTable> objects;
public List<OtherTable> getObjects() {
return objects;
}
public void setObjects(List<OtherTable> objects) {
this.objects = objects;
}
}
然后在普通的for循環中
for (MyTable myTable : collectionOfMyTables) {
myTable.getObjects();
}
當循環到達第三個myTable
時,將發生異常,該循環在第3個myTable
中的“ key_from_other_table”列中的值與collectionOfMyTables
集合中的任何先前的myTable
。
如果所有myTable
對象在“ key_from_other_table”列中具有不同的值,則不會發生異常。
例如:
MY_TABLE
id | key_from_other_table | some_values
---------------------------------------
1 | SET_A | xxx
2 | SET_B | yyy
3 | SET_C | zzz
OTHER_TABLE
id | key | more_values
------------------------
1 | SET_A | xxx_1
2 | SET_A | xxx_2
3 | SET_B | yyy_1
4 | SET_C | zzz_1
5 | SET_C | zzz_2
以上也不例外。
MY_TABLE
id | key_from_other_table | some_values
---------------------------------------
1 | SET_A | xxx
2 | SET_B | yyy
3 | SET_A | zzz
OTHER_TABLE
id | key | more_values
------------------------
1 | SET_A | xxx_1
2 | SET_A | xxx_2
3 | SET_B | yyy_1
4 | SET_C | zzz_1
5 | SET_C | zzz_2
以上是在讀取第三個myTable
時引起的異常。
但是給定MY_TABLE中允許相同的鍵值(即,多個MyTable實體可以共享OtherTable中的相同對象),如何解決此問題?
我聽說將獲取模式更改為急切可能可以解決此問題,但我希望使用懶惰獲取的解決方案,謝謝。
首先,對於OneToMany關聯,“許多”側的SQL表(即OtherTable)應具有指向“一個”側的主鍵(即MyTable)的外鍵。 在您的情況下,這意味着OtherTable應該具有一個名為“ myTableId”的列,該列指向MyTable中的“ id”。
這將導致ORM如下:
class MyTable {
@Id
private Integer id;
@OneToMany
@JoinColumn(name = "myTableId", referencedColumnName = "id")
List<OtherTable> otherTables;
}
但是,由於您聲明一個OtherTable可以是多個MyTable的成員,因此您需要一個ManyToMany關聯。 這涉及創建聯接表。 聯接表可能稱為MyTableOtherTable_JT。 該表將具有兩個外鍵列,一列指向MyTable的主鍵,名為myTableId,另一列指向OtherTable的主鍵,命名為otherTableId。
這將導致ORM如下:
class MyTable {
@Id
private Integer id;
@ManyToMany
@JoinTable(
name = "MyTableOtherTable_JT"
joinColumns=@JoinColumn(name = "myTableId", referencedColumnName = "id"),
inverseJoinColumns=@JoinColumn(name = "otherTableId", referencedColumnName = "id")
)
List<OtherTable> otherTables;
}
class OtherTable {
@Id
private Integer id;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.