- PR -

EJB3.0で、関連先がインスタンス化されない

投稿者投稿内容
hekigyoku
会議室デビュー日: 2008/12/16
投稿数: 17
投稿日時: 2008-12-18 21:43
> EJBで復帰するObjectはたとえLocalであっても元のObjectではありません。リモート
>インタフェースに変更できることを考えると別サーバのObjectにそのままアクセスでき
>ないとわかると思います。

EJBはリモートアクセスがありえるので、Detached状態のオブジェクトはもうデータベースとつながっていない事は理解しています。

> 基本的なObjectは復元されますが、リレーション先までは復元されないためそのまま
>では取得できません。仮にリレーション先を復元した場合、極端なことをいれば1つ
>のEntityを取得するのにDB全部を復元するような事態がありえるでしょう。

そのような危険を避けるために、EAGERフェッチとLAZYフェッチが存在するのではないでしょうか。

> なので、リレーション先のデータを取得する場合はEJBのインタフェースを考える
>必要があります。リレーション先のデータを取得するインタフェースを追加してもいい
>ですが、私の場合、EntityクラスがimplementするインタフェースでIDリストを返す
>ようにしておき、XMLに marhalしてインタフェースのObjectを復元するようにしてます。
>復元したEntityのリレーションはそのIDリストからIDで取得するようにしています。

marshal?このへん、ちょっとよく分かりません。
IDリストを返して・・・とやってしまうと、オブジェクト設計を壊す気がするのですが。

ちなみに、下のコードが、関連先までフェッチしてくれたものです。

@Stateless
public class EntityFinder{
...
Collection<Person> findPersonsByLastname(String lastname){
Query q = em.createNamedQuery("findPersonsByLastname");
q.setParameter("lastname",lastname);

Collection<Person> persons = q.getResultList();
for(Person p : persons) p.getGroup();

return persons;
}
つまり、必要な関連先は、全部SessionBeanのトランザクションの中で辿っておけ、
とそういう風に受け取れます。

結局のところ、EAGERフェッチであれば、わざわざこんな事をしなくても関連先まで
最初に取って来てくれるんじゃないの?
そうじゃなければ、EAGERフェッチって何なの?
というのが私の疑問なのです。
hekigyoku
会議室デビュー日: 2008/12/16
投稿数: 17
投稿日時: 2008-12-18 21:44
> EJBで復帰するObjectはたとえLocalであっても元のObjectではありません。リモート
>インタフェースに変更できることを考えると別サーバのObjectにそのままアクセスでき
>ないとわかると思います。

EJBはリモートアクセスがありえるので、Detached状態のオブジェクトはもうデータベースとつながっていない事は理解しています。

> 基本的なObjectは復元されますが、リレーション先までは復元されないためそのまま
>では取得できません。仮にリレーション先を復元した場合、極端なことをいれば1つ
>のEntityを取得するのにDB全部を復元するような事態がありえるでしょう。

そのような危険を避けるために、EAGERフェッチとLAZYフェッチが存在するのではないでしょうか。

> なので、リレーション先のデータを取得する場合はEJBのインタフェースを考える
>必要があります。リレーション先のデータを取得するインタフェースを追加してもいい
>ですが、私の場合、EntityクラスがimplementするインタフェースでIDリストを返す
>ようにしておき、XMLに marhalしてインタフェースのObjectを復元するようにしてます。
>復元したEntityのリレーションはそのIDリストからIDで取得するようにしています。

marshal?このへん、ちょっとよく分かりません。
IDリストを返して・・・とやってしまうと、オブジェクト設計を壊す気がするのですが。

ちなみに、下のコードが、関連先までフェッチしてくれたものです。

@Stateless
public class EntityFinder{
...
Collection<Person> findPersonsByLastname(String lastname){
Query q = em.createNamedQuery("findPersonsByLastname");
q.setParameter("lastname",lastname);

Collection<Person> persons = q.getResultList();
for(Person p : persons) p.getGroup();

return persons;
}
つまり、必要な関連先は、全部SessionBeanのトランザクションの中で辿っておけ、
とそういう風に受け取れます。

結局のところ、EAGERフェッチであれば、わざわざこんな事をしなくても関連先まで
最初に取って来てくれるんじゃないの?
そうじゃなければ、EAGERフェッチって何なの?
というのが私の疑問なのです。
だっちょ
大ベテラン
会議室デビュー日: 2006/12/05
投稿数: 115
投稿日時: 2008-12-19 16:20
 問題となっている現象が違うのかもしれませんが、
EntityManagerと関係なくEJB側で
コード:
// EJB側
@PermitAll
public Person getPerson() {
 Person = new Person();
 Person.group = new Group();
 return(Person);
}


でデータを取得したときに呼び出し元で
コード:
// 呼び出し元
 Person p = getPerson();
 if (p.group==null) {
// ここを通っている問題だと思っています。
 }



 上記問題なのであれば、EntityManagerの問題
というよりEJBのインタフェースの問題だと思ってます。

スキルアップ/キャリアアップ(JOB@IT)