我想知道,标题中的错误是什么意思 - 它经常发生在我的项目中,但它绝对没有感觉(显然,相关的类是神经元原始类型)。
在我看来,如果某些关系配置错误(例如注释中拼写错误的外部字段名称),则会抛出此错误 - 但错误不会提供有关它的信息。找到那些错误的关系是非常耗时的,我可以花这段时间在没有任何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;
}
}
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);
}
}
}
我还在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,但我不会将它们用于这两个类。我也有模型中每个其他类的接口(我知道这很奇怪,但我必须将它用于某些目的)。
非常感谢任何帮助,谢谢!
答案 0 :(得分: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
?更改架构时,需要重新生成配置文件。
答案 1 :(得分:0)
我遇到了同样的问题,虽然我不知道究竟是什么问题,但我确定它是由ormlite_config.txt文件引起的。删除文件后,将数据库助手类的构造函数更改为不使用ormlite_config.txt版本。一切都很好。
答案 2 :(得分:-1)
如果有人遇到类似的问题:不要在DatabaseHelper的构造函数中调用this.getWritableDatabase()。当我删除它时,代码神奇地开始工作 - 不知道,为什么会发生,但它确实有效。