Android ormlite SQLException при сохранении класса, содержащего ForeignCollection

Я хочу использовать ormlite для сохранения объекта, содержащего только ForeignCollection. Класс выглядит так:

@DatabaseTable(tableName="person")
public class Person {

    @DatabaseField(generatedId = true)
    private long id;

    @ForeignCollectionField
    private ForeignCollection<Pet> pets;

    public ForeignCollection<Pet> getPets() {
        return pets;
    }

    public long getId() {
        return id;
    }
}

Класс Pet выглядит следующим образом:

@DatabaseTable(tableName="pet")
public class Pet {

    public static final String PERSON_ID_FIELD_NAME = "person_id";

    @DatabaseField(generatedId = true)
    private long id;

    @DatabaseField
    private String name;

    @DatabaseField(foreign=true, foreignAutoRefresh=true, columnName = PERSON_ID_FIELD_NAME)
    private Person person;

[getters and setters snipped..]

Я сохраняю класс следующим образом:

Person person = new Person();
getHelper().getPersonDao().create(person);

Это приводит к сбою со следующим:

java.sql.SQLException: Unable to run insert stmt on object com.eniro.core.android.orm.Person@b4c33b78: INSERT INTO `person` () VALUES ()
        at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
        at com.j256.ormlite.stmt.mapped.MappedCreate.insert(MappedCreate.java:124)
        at com.j256.ormlite.stmt.StatementExecutor.create(StatementExecutor.java:394)
        at com.j256.ormlite.dao.BaseDaoImpl.create(BaseDaoImpl.java:308)
        at com.eniro.core.android.orm.DummyOrmTest.testPersistPerson(DummyOrmTest.java:27)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at junit.framework.TestCase.runTest(TestCase.java:154)
        at junit.framework.TestCase.runBare(TestCase.java:127)
        at junit.framework.TestResult$1.protect(TestResult.java:106)
        at junit.framework.TestResult.runProtected(TestResult.java:124)
        at junit.framework.TestResult.run(TestResult.java:109)
        at junit.framework.TestCase.run(TestCase.java:118)
        at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
        at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
        at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:545)
        at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551)
Caused by: java.sql.SQLException: inserting to database failed: INSERT INTO `person` () VALUES ()
at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
at com.j256.ormlite.android.AndroidDatabaseConnection.insert(AndroidDatabaseConnection.java:152)
at com.j256.ormlite.stmt.mapped.MappedCreate.insert(MappedCreate.java:89)
... 15 more
Caused by: android.database.sqlite.SQLiteException: near ")": syntax error: , while compiling: INSERT INTO `person` () VALUES ()
at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:68)
at android.database.sqlite.SQLiteProgram.compileSql(SQLiteProgram.java:143)
at android.database.sqlite.SQLiteProgram.compileAndbindAllArgs(SQLiteProgram.java:361)
at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:260)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:112)
at com.j256.ormlite.android.AndroidDatabaseConnection.insert(AndroidDatabaseConnection.java:140)
... 16 more

Если я добавлю в Person еще одно поле, например «имя», оно сработает. Но я просто хочу иметь класс, содержащий только коллекцию. Это возможно?


person Kjetil Eide    schedule 18.02.2013    source источник
comment
Таким образом, ответ лежит дальше по трассировке стека исключений. Я подозреваю, что есть сообщение «Причинено». Может нарушение ограничений? Публикация полной трассировки стека в любом случае рекомендуется.   -  person Gray    schedule 18.02.2013
comment
Извините, я обновил вопрос с полной трассировкой стека.   -  person Kjetil Eide    schedule 18.02.2013
comment
@Gray: Еще раз спасибо за инфраструктуру ORMLite :) Действительно ли есть способ указать хак нулевого столбца для постоянства ORMLite?   -  person Boris Strandjev    schedule 18.02.2013
comment
Нет. Извините, @BorisStrandjev.   -  person Gray    schedule 18.02.2013


Ответы (2)


Если я добавлю в Person еще одно поле, например «имя», оно сработает. Но я просто хочу иметь класс, содержащий только коллекцию. Это возможно?

К сожалению, нет. Коллекция Pet не является полем в таблице Person, поэтому вы в основном пытаетесь вставить поля в Person, потому что единственным полем является автоматически сгенерированный идентификатор.

Поэтому я бы, к сожалению, пока просто добавил поле маркера и задокументировал его необходимость из-за ограничений в ORMLite.

person Gray    schedule 18.02.2013

Тогда ставь сборник и все будет в порядке. Если вы не установите коллекцию, она останется нулевой. Я думаю, что ошибка, которую вы получаете, связана с проблемой взлома нулевого столбца, подробно описанной здесь.

EDIT На самом деле, даже предоставляя коллекцию, у вас все равно будут пустые значения, и вставка может завершиться ошибкой, если в ORMLite не установлено NullColumnHack.

person Boris Strandjev    schedule 18.02.2013