1

タイトルからのエラーはどういう意味ですか?私のプロジェクトでは非常に頻繁に発生しますが、まったく意味がありません(明らかに、関連するクラスは神経質なプリミティブ型です)。

一部のリレーションが誤って構成されている場合(アノテーションの外部フィールド名のスペルが間違っているなど)、このエラーがスローされるように見えますが、エラーはそれに関する情報を提供しません。それらの間違った関係を見つけるのは非常に時間がかかるので、ormなしでプレーンSQLでモデルを書くことにこの時間を費やすことができたでしょう!

また、何も問題がないという奇妙な状況に遭遇しましたが、「外部としてマークされたプリミティブ型」の例外が再度スローされます。以下はこの状況です。

モデル内の多くのテーブル(約50クラス)に沿って、次の2つを作成します。Tab1:

@DatabaseTable()
public class Tab1 {
    @DatabaseField(generatedId = true)
    int id;

    @ForeignCollectionField(eager = false, foreignFieldName = "tab1")
    Collection<Tab2> tab2;

    public Tab1() {
    }

    public int getId() {
            return id;
    }

    public void setId(int id) {
            this.id = id;
    }

    public Collection<Tab2> getTab2() {
            return tab2;
    }
}

Tab2:

@DatabaseTable()
public class Tab2 {
    @DatabaseField(generatedId = true)
    int id;

    @DatabaseField(foreign = true)
    Tab1 tab1;

    public Tab2() {
    }

    public Tab2(Tab1 tab1) {
            super();
            this.tab1 = tab1;
    }

    public int getId() {
            return id;
    }

    public void setId(int id) {
            this.id = id;
    }

    public Tab1 getTab1() {
            return tab1;
    }

    public void setTab1(Tab1 tab1) {
            this.tab1 = tab1;
    }
}

DatabaseHelperでdaosを作成します。

public class DatabaseHelper extends OrmLiteSqliteOpenHelper {

    private static final String DATABASE_NAME = "samplename.db";
    private static final String BACKUP_DATABASE_NAME = "samplename_bak.db";
    private static final int DATABASE_VERSION = 2;
    private static String DB_PATH = "/data/data/com.samplepath/databases/";

// DAOs

Dao<Tab1, Integer> tab1Dao;
Dao<Tab2, Integer> tab2Dao;
    // many other daos

    public Dao<Tab1, Integer> getTab1Dao() {
            try {
                    if (tab1Dao == null) {
                            tab1Dao = DaoManager.createDao(connectionSource, Tab1.class);
                    }
                    return tab1Dao;
            } catch (SQLException e) {
                    return null;
            }
    }

    public Dao<Tab2, Integer> getTab2Dao() {
            try {
                    if (tab2Dao == null) {
                            tab2Dao = DaoManager.createDao(connectionSource, Tab2.class);
                    }
                    return tab2Dao;
            } catch (SQLException e) {
                    return null;
            }
    }
    //many other dao getters

    public DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION, R.raw.ormlite_config);
            Log.i("dbTag", "Creating database from file...");
            SQLiteDatabase db = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
            try {
                    Log.i("dbTag", "Creating database....");
                    TableUtils.createTable(connectionSource, Tab1.class);
                    TableUtils.createTable(connectionSource, Tab2.class);
                    //other create tables
                    Log.i("Exception", "inserted");
            } catch (SQLException e) {
                    Log.i("Exception", "error - could not create database.");
                    Log.i("Exception", e.getMessage());
                    Log.e("Exception", "", e);
            }
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int oldVersion,
                    int newVersion) {
            try {
                    Log.i("dbTag", "onUpgrade");
                    Log.i("dbTag", "Dropping database....");
                    TableUtils.dropTable(connectionSource, Tab1.class, true);
                    TableUtils.dropTable(connectionSource, Tab2.class, true);
                    //other drops
                    Log.i("dbTag", "Creating database....");
                    onCreate(sqLiteDatabase, connectionSource);
            } catch (SQLException e) {
                    Log.e(DatabaseHelper.class.getName(), "Can't drop databases", e);
                    throw new RuntimeException(e);
            }
    }
}

また、この2つのクラスをconfig utilに含め、ormlite_config.txtファイルを作成します。私はroboguiceと一緒に基本アクティビティでデータベースヘルパーを管理します:

public class BaseActivity<T extends OrmLiteSqliteOpenHelper, E extends BaseErrorHandler> extends OrmLiteBaseActivity<T> implements RoboContext, IErrorHandler {

    protected EventManager eventManager;
    protected HashMap<Key<?>,Object> scopedObjects = new HashMap<Key<?>,Object>();
    protected E errorHandler;
    public static final DefaultHttpClient httpclient = new DefaultHttpClient();
    public static Map<String,String> args = null;

    @Inject
    ContentViewListener ignored; // do not use?

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        final RoboInjector injector = RoboGuice.getInjector(this);
        eventManager = injector.getInstance(EventManager.class);
        injector.injectMembersWithoutViews(this);
        super.onCreate(savedInstanceState);
        eventManager.fire(new OnCreateEvent(savedInstanceState));
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        eventManager.fire(new OnRestartEvent());
    }

    @Override
    protected void onStart() {
        super.onStart();
        eventManager.fire(new OnStartEvent());
    }

    @Override
    protected void onResume() {
        super.onResume();
        eventManager.fire(new OnResumeEvent());
    }

    @Override
    protected void onPause() {
        super.onPause();
        eventManager.fire(new OnPauseEvent());
    }

    @Override
    protected void onNewIntent( Intent intent ) {
        super.onNewIntent(intent);
        eventManager.fire(new OnNewIntentEvent());
    }

    @Override
    protected void onStop() {
        try {
            eventManager.fire(new OnStopEvent());
        } finally {
            super.onStop();
        }
    }

    @Override
    protected void onDestroy() {
        try {
            eventManager.fire(new OnDestroyEvent());
        } finally {
            try {
                RoboGuice.destroyInjector(this);
            } finally {
                super.onDestroy();
            }
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        final Configuration currentConfig = getResources().getConfiguration();
        super.onConfigurationChanged(newConfig);
        eventManager.fire(new OnConfigurationChangedEvent(currentConfig, newConfig));
    }

    @Override
    public void onContentChanged() {
        super.onContentChanged();
        RoboGuice.getInjector(this).injectViewMembers(this);
        eventManager.fire(new OnContentChangedEvent());
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        eventManager.fire(new OnActivityResultEvent(requestCode, resultCode, data));
    }

    public Map<Key<?>, Object> getScopedObjectMap() {
        return scopedObjects;
    }

    @Override
    public void handleError(int resId) {
        errorHandler.exceptionHandler(getString(resId), this);
    }

}

昼食活動では、次のコードを実行します。

Log.i("Tab1", "creating tab1");
getHelper().getTab1Dao();
Log.i("Tab1", "created tab1");
Log.i("Tab1", "creating tab2");
getHelper().getTab2Dao();
Log.i("Tab1", "created tab2");

アプリは最初にデバイスからアンインストールされ、次にインストールされて再度実行されます。これは私がログに見るものです:

03-14 11:22:54.400: I/DaoManager(31657): Loaded configuration for class com.xxx.xxx.model.Tab1
03-14 11:22:54.400: I/DaoManager(31657): Loaded configuration for class com.xxx.xxx.model.Tab2
03-14 11:22:54.423: I/dbTag(31657): Creating database from file...
03-14 11:22:54.486: I/dbTag(31657): Creating database....
03-14 11:22:54.494: I/TableUtils(31657): creating table 'tab1'
03-14 11:22:54.494: I/TableUtils(31657): executed create table statement changed 1 rows: CREATE TABLE `tab1` (`id` INTEGER PRIMARY KEY AUTOINCREMENT ) 
03-14 11:22:54.494: I/TableUtils(31657): creating table 'tab2'
03-14 11:22:54.501: I/TableUtils(31657): executed create table statement changed 1 rows: CREATE TABLE `tab2` (`id` INTEGER PRIMARY KEY AUTOINCREMENT , `tab1_id` INTEGER ) 
[...]
03-14 11:22:55.283: I/Tab1(31657): creating tab1
03-14 11:22:55.291: E/Tab1(31657): java.lang.IllegalArgumentException: Field FieldType:name=tab1,class=Tab2 is a primitive class class com.xxx.xxx.model.Tab1 but marked as foreign
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.field.FieldType.configDaoInformation(FieldType.java:315)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.BaseDaoImpl.initialize(BaseDaoImpl.java:200)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:126)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.BaseDaoImpl.<init>(BaseDaoImpl.java:117)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.BaseDaoImpl$5.<init>(BaseDaoImpl.java:911)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.BaseDaoImpl.createDao(BaseDaoImpl.java:911)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.DaoManager.doCreateDao(DaoManager.java:359)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.DaoManager.createDaoFromConfig(DaoManager.java:326)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.dao.DaoManager.createDao(DaoManager.java:55)
03-14 11:22:55.291: E/Tab1(31657):  at com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper.getDao(OrmLiteSqliteOpenHelper.java:239)
03-14 11:22:55.291: E/Tab1(31657):  at com.xxx.xxx.xxx.onCreate(XXX.java:43)
03-14 11:22:55.291: E/Tab1(31657):  at android.app.Activity.performCreate(Activity.java:4465)
03-14 11:22:55.291: E/Tab1(31657):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1053)
03-14 11:22:55.291: E/Tab1(31657):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1934)
03-14 11:22:55.291: E/Tab1(31657):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
03-14 11:22:55.291: E/Tab1(31657):  at android.app.ActivityThread.access$600(ActivityThread.java:128)
03-14 11:22:55.291: E/Tab1(31657):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
03-14 11:22:55.291: E/Tab1(31657):  at android.os.Handler.dispatchMessage(Handler.java:99)
03-14 11:22:55.291: E/Tab1(31657):  at android.os.Looper.loop(Looper.java:137)
03-14 11:22:55.291: E/Tab1(31657):  at android.app.ActivityThread.main(ActivityThread.java:4514)
03-14 11:22:55.291: E/Tab1(31657):  at java.lang.reflect.Method.invokeNative(Native Method)
03-14 11:22:55.291: E/Tab1(31657):  at java.lang.reflect.Method.invoke(Method.java:511)
03-14 11:22:55.291: E/Tab1(31657):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
03-14 11:22:55.291: E/Tab1(31657):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
03-14 11:22:55.291: E/Tab1(31657):  at dalvik.system.NativeStart.main(Native Method)

さらに、モデル内の他のすべてのクラスにカスタムdaosがありますが、この2つのクラスには使用しません。モデル内の他のすべてのクラスのインターフェイスもあります(これは奇妙なことですが、いくつかの目的のために必要です)。

どんな助けでも大歓迎です、ありがとう!

4

3 に答える 3

1

は。まあ、エラーは自明であるはずだった

Field FieldType:name=tab1,class=Tab2 is a primitive class 
    class com.xxx.xxx.model.Tab1 but marked as foreign

何らかの理由で、Tab2型にはtab1プリミティブ クラスとしてマークされたフィールドがあります。ただし、クラスでは、tab1フィールドは次のように定義されています。

@DatabaseField(foreign = true)
Tab1 tab1;

このクラスに関連付けられているデータベース構成ファイルを更新していない可能性はありますか? たぶん、以前は でしたがint、今はTab1? スキーマを変更するときは、構成ファイルを再生成する必要があります。

于 2013-03-14T13:57:52.053 に答える
0

私は同じ問題に出くわしましたが、問題の正確な内容はわかりませんが、ormlite_config.txt ファイルが原因であると確信しています。ファイルを削除したら、データベース ヘルパー クラスのコンストラクターを ormlite_config.txt バージョンを使用しないように変更します。すべてが正常に動作します。

于 2013-07-31T07:49:32.120 に答える
-1

誰かが同様の問題に遭遇した場合: DatabaseHelper のコンストラクターで this.getWritableDatabase() を呼び出さないでください。これを削除すると、コードが魔法のように機能し始めました-なぜそれが起こったのかわかりませんが、機能します.

于 2013-04-06T09:57:25.310 に答える