JDOを使用してデータストアを管理するGAE/Jアプリを開発しています。データなどと対話するための多数のエンドポイントを提供します。また、これらのエンドポイント用のJavascriptクライアントも開発しています。
状況:
まずToken getSessionToken(User usr)
、セッション トークンを生成してユーザーに割り当て、ユーザー トークンとセッション トークンの両方をデータストアに格納するエンドポイント メソッドがあります。
次にInfo getInfo(Token token)
、セッション トークンを受け取り、そのセッション トークンがユーザーに対応しているかどうかを確認し、対応している場合は情報を返す別のエンドポイント メソッドがあります。
問題
Javascript クライアントから最初のメソッドを呼び出すと、すべて問題ありません。次に、以前に取得したセッション トークンを使用して 2 番目のメソッドを呼び出すと、セッション トークンがどのユーザーにも対応していないというエラーが表示されます...
確認したところ、新しいセッション トークンがまだ保持されていないためにこのエラーが発生することがわかりました。
質問
私の現在の解決策は、Javascript クライアントが 2 番目のメソッドを 1 回呼び出すようにすることです。エラーが発生した場合は、しばらく待ってからもう一度呼び出します...もっと良い解決策はありますか?
編集:
これは、最初のメソッド呼び出しに含まれるコードで、なぜそんなに時間がかかるのかを理解するためのものです...
終点:
@ApiMethod(
name = "getSessionToken",
path = "get_session_token",
httpMethod = HttpMethod.GET
)
public SessionToken getSessionToken (@Named("email") String email, @Named("password") String password)
throws InternalServerErrorException {
SessionToken sessionToken = new UsersController().getSessionToken(email, password);
return sessionToken;
}
コントロール:
public SessionToken getSessionToken(String email, String password) throws InternalServerErrorException {
SessionToken sessionToken = null;
PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction txn = DatastoreServiceFactory.getDatastoreService().beginTransaction();
try {
DAO dao = new DAO(pm);
User user = dao.getUserByLogin(email, password);
dao.deleteSessionToken(user.getSessionToken());
sessionToken = SessionTokenManager.generateToken(user.getEmail(), user.getPassword());
user.setSessionToken(sessionToken);
user = dao.insertUser(user);
txn.commit();
} catch (Exception e) {
throw new InternalServerErrorException();
} finally {
if (txn.isActive()) {
txn.rollback();
}
pm.close();
}
return sessionToken;
}
ダオ:
public User getUserByLogin(String email, String password) throws InternalServerErrorException {
User user = null;
Query query = null;
try {
query = this.pm.newQuery(User.class);
query.setFilter("email == emailParam && password == passwordParam");
query.declareParameters("String emailParam, String passwordParam");
List<User> results = (List<User>) query.execute(email, password);
user = results.get(0);
} catch (Exception e) {
e.printStackTrace();
throw new InternalServerErrorException("Error in DAO.getUserByLogin()");
} finally {
query.closeAll();
}
return user;
}
/////
public void deleteSessionToken(SessionToken sessionToken) throws InternalServerErrorException {
try {
this.pm.deletePersistent(sessionToken);
} catch (Exception e) {
e.printStackTrace();
throw new InternalServerErrorException("Error in DAO.deleteSessionToken()");
}
}
/////
public User insertUser(User user) throws InternalServerErrorException {
try {
this.pm.makePersistent(user);
} catch (Exception e) {
e.printStackTrace();
throw new InternalServerErrorException("Error in DAO.insertUser()", e);
}
return user;
}
モデル:
@PersistenceCapable
public class User {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private String name;
@Persistent
private String email;
@Persistent
private String password;
@Persistent
private Folder rootFolder;
@Persistent
private SessionToken sessionToken;
@Persistent(defaultFetchGroup = "true")
private AccountContainer accountContainer;
//getters & setters
}
/////
@PersistenceCapable
public class SessionToken {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key key;
@Persistent
private String token;
@Persistent
private Long created;
@Persistent
private String sha1;
//getters & setters
}