非所有関係のGoogle App Engineの実装
-
10-07-2019 - |
質問
私の質問は、Google App Engineとの非所有関係の実装方法に関するベストプラクティスの質問です。 JDOを使用して永続化を行っており、Googleドキュメントで推奨されているように、所有していない関係のリストを次のように永続化しています。
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class User implements Serializable, UserDetails {
...
@Persistent
private List<Key> groups;
...
}
キーオブジェクトを使用してオブジェクトのリストを照会しようとすると、苦境に陥りました。そのため、実際にGroupオブジェクトのリストを返すためにグループキーのリストを取得するとき、オブジェクトを取得するためにそのキーを検索する必要があります。私の質問は、モデルオブジェクトで所有されていないルックアップを行う推奨される方法は何ですか?
ルックアップを行えるように、ModelオブジェクトにPersistanceManagerFactoryのインスタンスが必要ですか?
ルックアップできるように、ModelオブジェクトにGroupDAOオブジェクトのインスタンスが必要ですか?
このタイプの検索を実行するユーティリティが必要ですか?
私はこれが初めてなので、これを行うための最善の方法を知りたいだけです。ありがとう。
解決
理想的には、User
オブジェクトにはList<UnownedObject>
を返すメソッドがあるため、呼び出し元はクリーンなAPIを取得できます。そのための1つの方法は、PersistenceManager
オブジェクトがDAOのインスタンスを持ち、DAOにクエリを実行するように依頼することです。
これを行うには、リクエストの終了までUserDao
を閉じることができません。これを行う1つの方法は、サーブレットフィルターを作成することです。
public class PersistenceManagerFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
request.setAttribute("pm", pm);
chain.doFilter(request, response);
} finally {
pm.close();
}
}
}
その後、DAOにUser.setUserDao()
を挿入できます。 Guice を使用すると、次のことができます。
@RequestScoped
public class UserDao {
private final PersistenceManager pm;
@Inject
UserDao(PersistenceManager pm) {
this.pm = pm;
}
public User getUser(parameters) {
Key key = createKey(parameters);
User user = pm.getObjectById(User.class, key);
user.setUserDao(this);
return user;
}
}
これは、providePersistenceManager
がsetAttribute()
と同じパッケージにある場合に最適に機能するため、getAttribute()
をパッケージスコープにすることができます。 <=>の代わりに<=>オブジェクトに<=>を設定することもできます。
次に、バインドするGuiceモジュールを作成する必要があります<=>:
public class PersistenceManagerModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides @RequestScoped
PersistenceManager providePersistenceManager(HttpServletRequest request) {
return (PersistenceManager) request.getAttribute("pm");
}
}
最後に、 Guiceを使用するようにGoogle App Engineを構成する必要があります 。
これは、可能な方法の1つにすぎません。サーブレットフィルターで<=>を作成する代わりに、<=>で<=>を作成し、リクエスト属性として保存すると、より賢くなります(フィルターはそれを閉じます)。また、サーブレットフィルタにGuice Injectorを取得させて、<=>および<=>の使用を回避し、代わりによりタイプセーフなAPIを使用することもできます。
他のヒント
Google 推奨シングルトンPersistenceManagerFactoryを作成します。モデルにPMFを貼り付けません。