Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在集合上循环时休眠删除会话_Java_Hibernate_Jpa - Fatal编程技术网

Java 在集合上循环时休眠删除会话

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

我得到了这个异常LazyInitializationException:未能延迟初始化角色集合,无法初始化代理-在MyTable集合上循环时没有会话。e、 g:

当循环到达第三个myTable时会发生异常,在该表中,它在列key_from_other_table中的值与collectionOfMyTables集合中任何以前的myTable中的值相同

如果所有myTable对象在列键_中的值与其他_表中的值不同,则不会发生异常

e、 g:

上述情况也不例外

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;
}