我在 MyTable
集合上循环时遇到此异常 LazyInitializationException:无法延迟初始化角色集合,无法初始化代理 - 无 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
时,将发生异常,该列“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
以上也不异常(exception)。
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 中的相同对象),您如何解决这个问题?
我听说将获取模式更改为 eager 可能会解决此问题,但我更喜欢使用延迟获取的解决方案,谢谢。
最佳答案
首先,对于 OneToMany 关联,“多”端(即 OtherTable)的 SQL 表应该有一个指向“一”端(即 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;
}
关于java - 在集合上循环时 Hibernate 删除 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49291515/