ログ日記

作業ログと日記とメモ

Cayenne + Wicket のシリアライゼーション

もやもやしていたのでCayenneのデシリアライズHollowの状態についてメモ。
http://cayenne.apache.org/doc/persistent-object-lifecycle.html



CayenneDataObject.java

    private void writeObject(ObjectOutputStream out) throws IOException {
        out.writeInt(persistenceState);

        switch (persistenceState) {
            // New, modified or transient or deleted - write the whole shebang
            // The other states (committed, hollow) all need just ObjectId
            case PersistenceState.TRANSIENT:
            case PersistenceState.NEW:
            case PersistenceState.MODIFIED:
            case PersistenceState.DELETED:
                out.writeObject(values);
                break;
        }

        out.writeObject(objectId);
    }

    private void readObject(ObjectInputStream in) throws IOException,
            ClassNotFoundException {
        this.persistenceState = in.readInt();

        switch (persistenceState) {
            case PersistenceState.TRANSIENT:
            case PersistenceState.NEW:
            case PersistenceState.MODIFIED:
            case PersistenceState.DELETED:
                values = (Map<String, Object>) in.readObject();
                break;
            case PersistenceState.COMMITTED:
            case PersistenceState.HOLLOW:
                this.persistenceState = PersistenceState.HOLLOW;
                // props will be populated when required (readProperty called)
                values = new HashMap<String, Object>();
                break;
        }

        this.objectId = (ObjectId) in.readObject();

        // DataContext will be set *IF* the DataContext it came from is also
        // deserialized. Setting of DataContext is handled by the DataContext
        // itself
    }

状態がCOMMITTEDの場合はvalues(DBのデータに対応)はwriteObjectで保存されない。



Whenever such object is "touched" by the user (i.e. a setter or a getter is invoked), Cayenne automatically infaltes it with the database values.

http://cayenne.apache.org/doc/cayenne-contract.html

ここにはget系メソッドを呼び出せば自動的にselectされると書いてある。



しかし

    public Object readProperty(String propertyName) {
        if (objectContext != null) {
            // will resolve faults ourselves below as checking class descriptors for the
            // "lazyFaulting" flag is inefficient. Passing "false" here to suppress fault
            // processing
            objectContext.prepareForAccess(this, propertyName, false);
        }

        Object object = readPropertyDirectly(propertyName);

        if (object instanceof Fault) {
            object = ((Fault) object).resolveFault(this, propertyName);
            writePropertyDirectly(propertyName, object);
        }

        return object;
    }

objectContextがnullの場合は無視される。objectContextはシリアライズされていないので、単純にPersistentクラスをデシリアライズしただけではデータは復元されない。



上のコメントで

        // DataContext will be set *IF* the DataContext it came from is also
        // deserialized. Setting of DataContext is handled by the DataContext
        // itself

と書いてある。
これはもしかして…と思ってページクラスに@Injectアノテーションで取得していたObjectContextのオブジェクトを、コンストラクタで手動登録するようにした。
そしたらHollow状態にならなかった!
これは…。Guicewicket-guiceの動作を調べる必要があるかも。