#java #android #annotations #ormlite
#java #Android #аннотации #ormlite
Вопрос:
У меня возникает эта ошибка при запуске моего приложения для Android:
Ни у каких полей нет аннотации DatabaseField в классе [[Lmodel.Vak;
В моем классе Vak есть аннотации, поэтому я действительно не понимаю, почему он все еще выдает мне эту ошибку.
package model;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
@DatabaseTable(tableName = "vak")
public class Vak {
@DatabaseField(generatedId = true, columnName = "vakID", id=true) Long id;
@DatabaseField int rij;
@DatabaseField
int kolom;
...
}
У меня есть файл с именем Databasehelper.java в котором расширяется OrmLiteSqLiteOpenHelper и файл выглядит следующим образом:
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
// name of the database file for your application -- change to something
// appropriate for your app
private static final String DATABASE_NAME = "project56.db";
// any time you make changes to your database objects, you may have to
// increase the database version
private static final int DATABASE_VERSION = 1;
private DatabaseType databaseType = new SqliteAndroidDatabaseType();
// the DAO object we use to access the tables
private Dao<Vleugel, Long> vleugelDao = null;
private Dao<Verdieping, Long> verdiepingDao = null;
private Dao<NavigatiePunt, Long> navigatiePuntDao = null;
private Dao<Lokaal, Long> lokaalDao = null;
private Dao<Raster, Long> rasterDao = null;
private Dao<Vak, Long> vakDao = null;
private Dao<Graaf, Long> graafDao = null;
private Dao<Vertex, Long> vertexDao = null;
private Dao<Edge, Long> edgeDao = null;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* This is called when the database is first created. Usually you should
* call createTable statements here to create the tables that will store
* your data.
*/
@Override
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
try {
Log.i(DatabaseHelper.class.getName(), "onCreate");
TableUtils.createTable(connectionSource, Vleugel.class);
TableUtils.createTable(connectionSource, Verdieping.class);
TableUtils.createTable(connectionSource, NavigatiePunt.class);
TableUtils.createTable(connectionSource, Lokaal.class);
TableUtils.createTable(connectionSource, Raster.class);
TableUtils.createTable(connectionSource, Vak.class);
TableUtils.createTable(connectionSource, Graaf.class);
TableUtils.createTable(connectionSource, Vertex.class);
TableUtils.createTable(connectionSource, Edge.class);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't create database", e);
throw new RuntimeException(e);
}
}
/**
* This is called when your application is upgraded and it has a higher
* version number. This allows you to adjust the various data to match the
* new version number.
*/
@Override
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource,
int oldVersion, int newVersion) {
try {
Log.i(DatabaseHelper.class.getName(), "onUpgrade");
TableUtils.dropTable(connectionSource, Vleugel.class, true);
TableUtils.dropTable(connectionSource, Verdieping.class, true);
TableUtils.dropTable(connectionSource, NavigatiePunt.class, true);
TableUtils.dropTable(connectionSource, Lokaal.class, true);
TableUtils.dropTable(connectionSource, Raster.class, true);
TableUtils.dropTable(connectionSource, Vak.class, true);
TableUtils.dropTable(connectionSource, Graaf.class, true);
TableUtils.dropTable(connectionSource, Vertex.class, true);
TableUtils.dropTable(connectionSource, Edge.class, true);
// after we drop the old databases, we create the new ones
onCreate(db, connectionSource);
} catch (SQLException e) {
Log.e(DatabaseHelper.class.getName(), "Can't drop databases", e);
throw new RuntimeException(e);
}
}
/**
* Returns the Database Access Object (DAO) for the classes It will create
* it or just give the cached value.
*/
public Dao<Vleugel, Long> getVleugelDao() throws SQLException {
if (vleugelDao == null) {
vleugelDao = getDao(Vleugel.class);
}
return vleugelDao;
}
public Dao<Verdieping, Long> getVerdiepingDao() throws SQLException {
if (verdiepingDao == null) {
verdiepingDao = getDao(Verdieping.class);
}
return verdiepingDao;
}
public Dao<NavigatiePunt, Long> getNavigatiePuntDao() throws SQLException {
if (navigatiePuntDao == null) {
navigatiePuntDao = getDao(NavigatiePunt.class);
}
return navigatiePuntDao;
}
public Dao<Lokaal, Long> getLokaalDao() throws SQLException {
if (lokaalDao == null) {
lokaalDao = getDao(Lokaal.class);
}
return lokaalDao;
}
public Dao<Raster, Long> getRasterDao() throws SQLException {
if (rasterDao == null) {
rasterDao = getDao(Raster.class);
}
return rasterDao;
}
public Dao<Vak, Long> getVakDao() throws SQLException {
if (vakDao == null) {
vakDao = getDao(Vak.class);
}
return vakDao;
}
public Dao<Graaf, Long> getGraafDao() throws SQLException {
if (graafDao == null) {
graafDao = getDao(Graaf.class);
}
return graafDao;
}
public Dao<Vertex, Long> getVertexDao() throws SQLException {
if (vertexDao == null) {
vertexDao = getDao(Vertex.class);
}
return vertexDao;
}
public Dao<Edge, Long> getEdgeDao() throws SQLException {
if (edgeDao == null) {
edgeDao = getDao(Edge.class);
}
return edgeDao;
}
/**
* Close the database connections and clear any cached DAOs.
*/
@Override
public void close() {
super.close();
vleugelDao = null;
verdiepingDao = null;
navigatiePuntDao = null;
lokaalDao = null;
rasterDao = null;
vakDao = null;
graafDao = null;
vertexDao = null;
edgeDao = null;
}
}
У меня также есть файловый контроллер, который расширяет OrmLiteBaseActivity:
public class Controller extends OrmLiteBaseActivity<DatabaseHelper> {
Dao<Vleugel, Long> vleugelDao;
Dao<Verdieping, Long> verdiepingDao;
Dao<NavigatiePunt, Long> navigatiePuntDao;
Dao<Lokaal, Long> lokaalDao;
Dao<Raster, Long> rasterDao;
Dao<Graaf, Long> graafDao;
Dao<Vertex, Long> vertexDao;
Dao<Edge, Long> edgeDao;
Dao<Vak, Long> vakDao;
// Databasehelper is benodigd voor ORMLite
static {
OpenHelperManager.setOpenHelperFactory(new SqliteOpenHelperFactory() {
public OrmLiteSqliteOpenHelper getHelper(Context context) {
return new DatabaseHelper(context);
}
});
}
public Controller() throws SQLException {
/** initialiseren van dao */
vleugelDao = getHelper().getVleugelDao();
verdiepingDao = getHelper().getVerdiepingDao();
navigatiePuntDao = getHelper().getNavigatiePuntDao();
lokaalDao = getHelper().getLokaalDao();
rasterDao = getHelper().getRasterDao();
graafDao = getHelper().getGraafDao();
vertexDao = getHelper().getVertexDao();
edgeDao = getHelper().getEdgeDao();
vakDao = getHelper().getVakDao();
}
/**
* Haalt vleugel idNaam op uit dao object bijv. K1
*
* @return Vleugel
* @throws java.sql.SQLException
*/
public Vleugel getVleugel(String vleugelIDNaam)
throws java.sql.SQLException {
// select * from vleugel where idNaam='{vleugelIDNaam}'
QueryBuilder<Vleugel, Long> qb = vleugelDao.queryBuilder();
Where where = qb.where();
// the name field must be equal to "foo"
where.eq("idNaam", vleugelIDNaam);
PreparedQuery<Vleugel> preparedQuery = qb.prepare();
List<Vleugel> vleugelList = vleugelDao.query(preparedQuery);
Log.v("Getvleugel", vleugelList.size() "");
if (vleugelList.size() == 1) {
return vleugelList.get(0);
}
return null;
}
public Verdieping getVerdieping(int nummer) throws java.sql.SQLException {
// TODO: Met querybuilder query naar db om verdieping te pakken
return null;
}
/**
* Haalt navigatiepunt op
*
* @param naam
* @return
* @throws java.sql.SQLException
*/
public NavigatiePunt getNavigatiePunt(String naam)
throws java.sql.SQLException {
// select * from navigatiepunt where naam='{naam}'
QueryBuilder<NavigatiePunt, Long> qb = navigatiePuntDao.queryBuilder();
Where where = qb.where();
where.eq("naam", naam);
PreparedQuery<NavigatiePunt> preparedQuery = qb.prepare();
List<NavigatiePunt> navigatieList = navigatiePuntDao
.query(preparedQuery);
Log.v("GetLokaal", navigatieList.size() "");
if (navigatieList.size() == 1) {
return navigatieList.get(0);
}
return null;
}
/**
* Get lokaal object op basis van lokaalcode
*
* @param lokaalcode
* @return
* @throws java.sql.SQLException
*/
public Lokaal getLokaal(String lokaalcode) throws java.sql.SQLException {
// select * from lokaal where lokaalcode='{lokaalcode}'
QueryBuilder<Lokaal, Long> qb = lokaalDao.queryBuilder();
Where where = qb.where();
where.eq("lokaalcode", lokaalcode);
PreparedQuery<Lokaal> preparedQuery = qb.prepare();
List<Lokaal> lokaalList = lokaalDao.query(preparedQuery);
Log.v("GetLokaal", lokaalList.size() "");
if (lokaalList.size() == 1) {
return lokaalList.get(0);
}
return null;
}
}
Итак, у вас есть какие-либо советы по этому поводу, что мне следует проверить?
Комментарии:
1.
@DatabaseField(generatedId = true, columnName = "vakID", id=true) Long id;
Насколько я знаю, вы могли бы использовать либо generatedId, либо id, но не оба одновременно.
Ответ №1:
Не могли бы вы проверить, создана ли таблица Vak в вашей базе данных? Отсутствие этой таблицы может быть причиной этого сбоя.
Ответ №2:
Оказалось, что это ошибка в ORMLite, связанная с циклами внешних объектов, которая была исправлена в версии 4.22. ORMLite неправильно передавал случай, когда A имеет внешнее поле B, у которого есть внешнее поле, в C, у которого есть внешнее поле, обратно в A..
Пожалуйста, пришлите мне прямое электронное письмо @Yanny, если это сработает или нет, и я соответствующим образом настрою этот ответ.
Ответ №3:
Вероятно, уже поздно давать решение, но это мое решение:
вы видите, что proguard пытается запутать код, и если вы прочитаете proguard подробно или вступление
http://proguard.sourceforge.net/FAQ.html
что такое сжатие в proguard -> Программы сжатия, такие как ProGuard, могут анализировать байт-код и удалять неиспользуемые классы, поля и методы. исходя из этого, мы можем предположить, что он удаляет ваши объекты, поскольку он нигде не используется…
итак, что вам, вероятно, нужно? вам нужно запретить proguard удалять эти методы или объекты из процесса, поэтому для этого есть строка..:
-keep class com.j256.**<br>
-keepclassmembers class com.j256.** { *; }<br>
-keep enum com.j256.**<br>
-keepclassmembers enum com.j256.** { *; }<br>
-keep interface com.j256.**<br>
-keepclassmembers interface com.j256.** { *; }
эта строка не позволит proguard удалить мои общедоступные методы и переменные..
-keepclassmembers class classpath.** {
public *;
}
вам нужно написать имя столбца для самого быстрого идентификатора … потому что он будет искать его и автоматически изменит его имя… итак, вам нужно определить идентификатор имени столбца для первичного ключа..