2017-07-14 3 views
0

私は、ハイバーネーションと野蛮なJava EEアプリケーションを構築しました。サーブレットは使用しませんでしたが、RESTful WebService用のJava APIで構築されたREST API。私のモデルが大きくなったので、私はFetchType.EAGERからFetchType.LAZYにコレクションを設定しました。今私はメッセージcould not initialize proxy - no SessionLazyInitializationExceptionを得ています。私はなぜこれが起こっているのか理解していると思うが、私は休止状態がプロキシにアクセスしようとしている時を理解していない。3層のJava eeアプリケーション内でのHibernateの遅延読み込み

エンティティ:

@Entity 
public class User implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    @Version 
    private Timestamp lastChanged; 

    @NotNull 
    private Date creationDate; 

    @ManyToMany 
    private Set<Entity> lazyEntity; 

    public User() { } 

    // getters and setters 
} 

DAO:

public interface UserDAO { 
    public List<User> getAll(); 
} 

豆:

@Stateless 
@Remote(UserDAO.class) 
public class UserBean<User> implements UserDAO { 

    @PersistenceContext 
    protected EntityManager em; 

    @Override 
    public List<User> getAll() { 
     return this.em.createQuery("SELECT u FROM User u ORDER BY u.creationDate", User.class) 
         .getResultList(); 
    } 
} 

ENDP OINT:lazyEntityは同じようにnullを返されていませんが、エラーがスローされた理由を

@Path("/users") 
@Stateless 
public class UsersEndpoint { 

    @EJB 
    private UserDAO userDAO; 

    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response getAll() { 
     List<User> users = userDAO.getAll(); 
     if (users.size() == 0) 
      return Response.status(Response.Status.NOT_FOUND) 
          .build(); 
     return Response.ok(users).build(); 
    } 
} 

私の質問はありますか?上記のコードでわかるように、APIエンドポイント内でアクセスしようとしないため、lazyEntityにアクセスしようとしている部分が休止状態です。私は例外をキャッチすることができますか?

例外を発生させずにオブジェクトを以下のように受け取るにはどうすればよいですか?私はすでにプロパティーhibernate.enable_lazy_load_no_transを変更して無効にすることができることを見てきました。しかし、私もreadこれは強く推奨されていません。

User { 
    id: 1, 
    lastChanged: 0981283812738, 
    creationDate: 2178371283098, 
    lazyEntity: null 
} 

答えて

1

私はこの問題は、(法上の注釈によってトリガ)UsersEndpoint内のgetAll()メソッドの結果のJSONにシリアライズしていると思います。

Jersey + Jackson(一般的なJava < - > JSONコンバータ)を使用すると仮定します。

getAll()メソッドが完了すると、Jacksonはメソッドの結果を取得し、Userクラスのすべてのデータを取得してJSONに変換しようとします。これを行うために、JacksonはUserクラスのgetLazyEntity()を呼び出し、遅延ロードされているのでデータベースアクセスをトリガーします(セッションが終了しているため失敗します)。

"lazyEntity"のデータをJSONレスポンスに含めるには、セッションを閉じる前にデータをフェッチする必要があります.HDAクエリでフェッチ結合を使用してDAO内部でデータをフェッチする必要があります。

JSONでlazyEntityを使用しない場合は、lazyEntityをシリアル化しないようにJacksonに指示する必要があります。ジャクソンのビューで行うことができます。 How can a @JsonView working with jerseyおよびhttp://wiki.fasterxml.com/JacksonJsonViewsを参照してください。

+0

ありがとうございます。しかし、私は '@ JsonView'アノテーションを見つけることができません。別の方法がありますか? – user289520

+0

さて、私はそれを得た。しかし、 '@ JsonView'の代わりに' @JsonIgnore'を使用しました。私はこれがはるかに少ないコードだと思いますか? – user289520

+0

@ JsonViewは面倒です。その利点は、オブジェクトのすべての属性とオブジェクトの一部だけを直列化する他のエンドポイントを直列化するいくつかのエンドポイントを持つことを可能にする、いくつかの '@ JsonView'に属性をマップできることです。 – PCO

関連する問題