Java 在集合上循环时休眠删除会话
我得到了这个异常LazyInitializationException:未能延迟初始化角色集合,无法初始化代理-在MyTable集合上循环时没有会话。e、 g: 当循环到达第三个myTable时会发生异常,在该表中,它在列key_from_other_table中的值与collectionOfMyTables集合中任何以前的myTable中的值相同 如果所有myTable对象在列键_中的值与其他_表中的值不同,则不会发生异常 e、 g: 上述情况也不例外Java 在集合上循环时休眠删除会话,java,hibernate,jpa,Java,Hibernate,Jpa,我得到了这个异常LazyInitializationException:未能延迟初始化角色集合,无法初始化代理-在MyTable集合上循环时没有会话。e、 g: 当循环到达第三个myTable时会发生异常,在该表中,它在列key_from_other_table中的值与collectionOfMyTables集合中任何以前的myTable中的值相同 如果所有myTable对象在列键_中的值与其他_表中的值不同,则不会发生异常 e、 g: 上述情况也不例外 MY_TABLE id | key_fr
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_表中允许相同的键值,即多个MyTable实体可以共享来自OtherTable的相同对象,您如何解决这个问题
我听说将fetch模式更改为eager可能会解决这个问题,但我更喜欢使用lazy fetch的解决方案,谢谢。首先,对于OneToMany关联,“多”端(即OtherTable)的SQL表应该有一个外键,指向“一”端(即MyTable)的主键。在您的例子中,这意味着OtherTable应该有一个名为“myTableId”的列,该列指向MyTable中的“id” 这将导致ORM本身:
class MyTable {
@Id
private Integer id;
@OneToMany
@JoinColumn(name = "myTableId", referencedColumnName = "id")
List<OtherTable> otherTables;
}
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;
}
但是,由于您声明一个OtherTable可以是多个MyTables的成员,因此需要多个关联。这涉及到创建联接表。联接表可以称为MyTableOtherTable_JT。该表将有两个外键列,一个指向MyTable的主键,名为myTableId,另一个指向OtherTable的主键,名为otherTableId
这将导致ORM本身:
class MyTable {
@Id
private Integer id;
@OneToMany
@JoinColumn(name = "myTableId", referencedColumnName = "id")
List<OtherTable> otherTables;
}
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;
}
LazyInitializationException发生的原因是,当触发延迟加载时,hibernate的会话关闭,但原因可能有很多。你能补充一些细节吗?就像OtherTable.class上关系的定义一样,如何打开和关闭会话,以及for循环中是否有某种逻辑。@BaptisteBeauvais,谢谢。你认为它可能是一个一个的注释,但实际上我的数据可能是很多的吗?非常感谢你提供的详细信息。我可以想象设置不太适合使用。我会更改它,但你认为是注释的不同使用导致了我看到的异常吗?这可能与你将关联视为一个单一而不是许多的事实有关。在这种情况下,我想象hibernate希望必须从数据库中查找对象,但该对象从第一次加载时就已经在其持久性上下文中,这可能导致了您的异常。不过,不要引用我的话:。再次感谢。所以我知道你的额外连接表是正确的方法,但是有没有一种方法可以在没有连接表的情况下解决我的问题,即只有两个表?我在问题中增加了一些例子来说明数据。
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;
}