2

以下のコードはエラーを引き起こしException in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.model.entity.WorkflowProcessEntity.workstations, no session or session was closedます。@Transactionalそのため、サービスクラス内でメソッドをラップしましたが、それでもエラーがスローされます。

    WorkstationService workstationService = (WorkstationService) ApplicationContextProvider.getApplicationContext().getBean("workstationService");
    for (WorkstationEntity workstationEntity : workstationService.getWorkstations(getEntity())) {
        registerWorkstation(new ImpositionWorkstation(workstationEntity));
    }

WorkstationService.java

@Transactional(readOnly = true)
public Collection<WorkstationEntity> getWorkstations(WorkflowProcessEntity workflowProcessEntity) {
    return workflowProcessEntity.getWorkstations();
}

WorkflowProcessEntity.java

@OneToMany(mappedBy = "workflowProcess")
@JsonIgnore
public Collection<WorkstationEntity> getWorkstations() {
    return workstations;
}

この関係を正しく照会するにはどうすればよいですか?

4

1 に答える 1

6

コードには 2 つの問題があります。

まず、デタッチされたエンティティをトランザクション サービスに渡し、エンティティが自動的にアタッチされることを期待します。そうではなく、切り離されたエンティティは切り離されており、トランザクション内にいるかどうかに関係なく、切り離されたエンティティから遅延プロパティを読み込もうとすると例外が発生します。それをロードするには、エンティティを ID でセッションからリロードしてから、このアタッチされたエンティティから遅延コレクションをロードする必要があります。

次に、エンティティからコレクションを取得すると、それが読み込まれると想定しています。そうでもない。コレクションは遅延ロードされたプロキシとして実装され、コレクションを取得して返すことは、プロキシを取得 (ユニット化) して返すことだけです。プロキシがそれ自体を初期化するのは、コレクションのメソッドを呼び出すときだけです。たとえば、コレクションを反復処理する場合。そして、それはトランザクションの外で行われます。スタック トレースを提供していれば、例外 io がサービス内からスローされたのではなく、サービス外の反復からスローされたことを確認できたはずです。

于 2013-07-15T21:55:17.453 に答える