3

GAE コードを実行しようとしています。エンコードされたキーを使用してユーザーを取得する際に問題があります。

シングルトン PMF を使用してすべての CRUD トランザクションを管理するこの User Data Manager クラスがあります。

エンコードされた文字列をキーとして使用するユーザーがいます。

public class Users implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private String encodedKey;
@Persistent
@Extension(vendorName = "datanucleus", key = "gae.pk-id", value = "true")
private Long keyId;
 --- code continues ----

DMクラスにこのcreateUserメソッドがあります

public static void createUser(Users user) {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
        Key key = KeyFactory.createKey(Users.class.getSimpleName(),
                user.getEmail());
        user.setEncodedKey(KeyFactory.keyToString(key));
        pm.makePersistent(user);
    } catch (Exception e) {
        logger.log(Level.SEVERE, e.toString());
    } finally {
        pm.close();
    }
}

問題は、取得する次のコードにあります。

    public static Users retrieveUser(String encodedKey) {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    Users user = null;
    try {
//          Key key = KeyFactory.createKey(Users.class.getSimpleName(),
//                  user.getEmail());
// I tried recreating the key with user's email, but it does not work either            
        pm.getObjectById(KeyFactory.stringToKey(encodedKey));
    } catch (Exception e) {
        logger.severe(e.toString());
    } finally {
        pm.close();
    }
    return user;
}

次のエラーが表示されます。

 SEVERE: javax.jdo.JDOObjectNotFoundException: No such object
 FailedObject:Users("t")
 NestedThrowables:org.datanucleus.exceptions.NucleusObjectNotFoundException: No such object

とにかく、「t」はダミーユーザーのメールです。

PMF を使用してエンティティを取得するには、encodedKey をどのように使用すればよいですか? 現在、私は電子メールとクエリを使用して識別することに頼っていますが、キーによるオブジェクトの取得は機能するはずです。

編集

モデル オブジェクトに次の変更を加えました。

@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
private String encodedKey;
@Persistent
@Extension(vendorName="datanucleus", key="gae.pk-name", value="true")
private String keyName;

これとGoogleのドキュメントに基づいて:

アプリは、名前付きのキーを使用して保存する前にこの値を設定することも、null のままにすることもできます。エンコードされたキー フィールドが null の場合、オブジェクトが保存されるときに、フィールドにはシステム生成キーが入力されます。

これを永続化するだけでうまくいくと思いました:

public static void createUser(Users user) {
    PersistenceManager pm = PMF.get().getPersistenceManager();
    try {
        user.setKeyName(user.getEmail()); 
        pm.makePersistent(user);
    } catch (Exception e) {
        logger.log(Level.SEVERE, e.toString());
    } finally {
        pm.close();
    }
}

しかし、そのような運はありません。キーネームを最初に設定したかどうかに関係なく、このエラーがスローされます。

SEVERE: javax.jdo.JDOFatalUserException: Invalid primary key for entity.Users.  Cannot have a null primary key field if the field is unencoded and of type String.  Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long.
NestedThrowables:
org.datanucleus.exceptions.NucleusFatalUserException: Invalid primary key for entity.Users.  Cannot have a null primary key field if the field is unencoded and of type String.  Please provide a value or, if you want the datastore to generate an id on your behalf, change the type of the field to Long.

わかりません。新しいエンティティの新しいキーが生成されないのはなぜですか? これらすべての問題により、Keyに戻ることを考えています。Androidクライアントにデータを提供するためにGAEサーバーを使用しているため、encodedKeyの方が移植性が高いと思いました。

4

2 に答える 2

1

そのフィールドに値を生成するようにマークしたときにsetEncodedKey ()を呼び出すポイントは何ですか? ( valueStrategy=IDENTITYを使用)。何かが生成された場合 (DB に挿入されたときなど)、setEncodedKeyに渡された値は無視されます。これは、 pm.getObjectId(obj)を呼び出すことで明確にわかります。

于 2012-10-11T16:53:06.473 に答える
0

クラスに注釈を付ける必要があります@PersistenceCapable。詳細については、JDO を使用したデータ クラスの定義を参照してください。

于 2012-10-11T16:37:19.543 に答える