0

次のようなインターフェイスを実装する必要があるいくつかのクラスを永続化したいと思います。

@DatabaseTable(tableName = "conditions")
abstract public class Condition implements Configurable {

    @DatabaseField(id = true, foreign = true)
    private Accion belong_to;

    @DatabaseField
    private HashMap<String, String> config = new HashMap<String, String>();

    @DatabaseField
    protected String className = this.getClass().getName();

    protected final HashMap<String, String> getConfig() {/* */}
    protected final void setConfig(HashMap<String, String> config) {/* */}
    protected void setConfig(String string, String value) {/* */}
    abstract public String getName();
    abstract public int getImageResource();
    abstract public String getShortDesc();
}

問題は、作成時に正しい子をインスタンス化する必要があることですCondition(条件自体が抽象的であるため)。

DAO を作成するときにそれを行う方法はありますか (そのために className を記録します)。または、他の方法でこれを行う必要がありますか?

Accionオブジェクトには 1 つのオブジェクトがアタッチされている必要がありますCondition。Accion も永続化されているため、Conditions を取得する方法も Dao 経由です。


更新: Java が Configurable オブジェクトをシリアル化できるように使用しpublic interface Configurable extends Serializable { /*...*/ }ており、それを Accion オブジェクトに格納します。

それはうまくいくでしょうか?

4

1 に答える 1

0

Classes stored should not be abstract classes due to ClassInstantiationException because class reflection is used to instantiate the retrieved records.

There is a work around posted here using wrapper classes but my method so far has been to store the "class", in my case serverType, as a field and when retrieving the base class passing the base class to a constructor of the wanted child class and copy it's properties.

Usage

        Dao<BaseConnectionInfo, Integer> connections = DatabaseManager
                .getInstance(this).getDatabaseHelper()
                .getDao(BaseConnectionInfo.class);

        BaseConnectionInfo connection = connections.queryForId(1);

        if (connection.isServerType(BaseConnectionInfo.SERVER_TYPE_MSSQL)) {
            connection = new MsSqlConnectionInfo(connection);
        } else if (connection
                .isServerType(BaseConnectionInfo.SERVER_TYPE_MYSQL)) {
            connection = new MySqlConnectionInfo(connection);
        }

BaseConnectionInfo

@DatabaseTable(tableName = "connections")
public class BaseConnectionInfo implements SqlDriverInterface {

    public static final String TAG = "BaseConnection";

    public static final String SERVER_TYPE_MYSQL = "MYSQL";
    public static final String SERVER_TYPE_MSSQL = "MSSQL";
    public static final String SERVER_TYPE_SYBASE = "SYBASE";
    public static final String SERVER_TYPE_POSTGRESQL = "POSTGRESQL";

    @DatabaseField(generatedId = true)
    private int id;

    @DatabaseField
    protected String serverType;

    @DatabaseField
    private String name;

    ...

    public boolean isServerType(String serverType) {
        return this.serverType.equals(serverType);
    }

    ...
}

MySqlConnectionInfo

public class MySqlConnectionInfo extends BaseConnectionInfo {

    public MySqlConnectionInfo() {
        // FOR ORMLITE
        serverType = SERVER_TYPE_MYSQL;
    }

    /**
     * Constructor used to convert {@link BaseConnectionInfo} to
     * {@link MySqlConnectionInfo}
     * 
     * @param baseConnectionInfo
     */
    public MySqlConnectionInfo(BaseConnectionInfo b) {
        setId(b.getId());
        setName(b.getName());
        setHost(b.getHost());
        setOptionsJson(b.getOptionsJson());
    }
    ...
}

MsSqlConnectionInfo

public class MsSqlConnectionInfo extends BaseConnectionInfo {

    public MsSqlConnectionInfo() {
        // FOR ORMLITE
        serverType = SERVER_TYPE_MSSQL;
    }

    /**
     * Constructor used to convert {@link BaseConnectionInfo} to
     * {@link MsSqlConnectionInfo}
     * 
     * @param baseConnectionInfo
     */
    public MsSqlConnectionInfo(BaseConnectionInfo b) {
        setId(b.getId());
        setName(b.getName());
        setHost(b.getHost());
        setOptionsJson(b.getOptionsJson());
    }
    ...
 }
于 2013-03-03T08:50:25.310 に答える