1

我想知道,标题中的错误是什么意思-它在我的项目中经常发生,但绝对没有意义(显然,相关的类是神经元的原始类型)。

在我看来,如果某些关系配置错误(如注释中拼写错误的外部字段名称),则会引发此错误 - 但该错误未提供有关它的信息。找到那些错误的关系非常耗时,以至于我本可以花时间在没有任何 orm 的普通 sql 中编写我的模型!

我也遇到了一个奇怪的情况,在这种情况下我没有发现任何问题——但是再次抛出了“标记为外来的原始类型”异常。下面是这种情况。

沿着模型中的许多表(大约 50 个类),我创建了这两个: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;
    }
}

表 2:

@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);
            }
    }
}

我还在 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,但我不将它们用于这两个类。我还为模型中的所有其他类提供了接口(我知道这很奇怪,但出于某些目的我必须拥有它)。

任何帮助将不胜感激,谢谢!

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 回答