Android ORMLite 4.38 allowGeneratedIdInsert导致IllegalStateException

时间:2013-02-02 02:33:14

标签: android ormlite

我定位Android 2.2及更新版本。在运行4.x的设备上生成此错误。我正在使用ORMLite 4.38库。

我需要保证每个记录实例对于任意数量的设备都是唯一的。我很高兴看到ORMLite支持UUID作为ID。我已经为我的数据库记录定义创建了一个UUID-id抽象基类。 allowGeneratedIdInsert是完美的解决方案。但是这个功能似乎导致了一个IllegalStateException:无法在dao'中创建数据元素。我通过删除此注释进行测试,没有问题。把它放回......同样的问题。将基类的东西放在一个记录定义中......同样的问题。

LogCat还报告:

  

引起:java.sql.SQLException:无法在对象上运行insert stmt - objectid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx

public abstract class UUIDDaoEnabled<T> extends BaseDaoEnabled<T, UUID> {

    //allowGeneratedIdInsert allows us to set UUID when this device db didn't create it
    @DatabaseField(generatedId = true, allowGeneratedIdInsert=true)
    private UUID id;
    ...
    public void setUUIDFromSerializedSource(SerializedModelBinaryInputStream stream, Dao<T, UUID> dao) throws SQLException { //only place we can set UUIDs
        if(id == null)
            dao.refresh((T)this); 

        if(id != null)
            throw new SQLException("Trying to set UUID on existing object");

        id = stream.getCurrentUUID();
    }
    }

我会像这样专注:

@DatabaseTable()
public class Type extends UUIDDaoEnabled<Type> { ... }

我无法从allowGeneratedIdInsertgeneratedId的文档中解释这一点。事实上,alloeGeneratedIdInsert的文档说它覆盖了generatedId的默认行为。它还说

  

仅当数据库支持此行为时才有效

然而,我在其他帖子中读到ORMLite 4.25(?)和更新版本在Android设备上支持此行为。所以,要么这不完全正确。或者我做一些蠢事......任何人???

更新:在考虑了一分钟后,我意识到allowGeneratedIdInsert支持和继承都不是根本原因,因为我基于相同的抽象类实例化其他对象。我无法弄清楚的是为什么一个特定的班级导致了这个问题。关于违规记录类型的唯一独特之处(与创建的其他类型相比)是一对多中的许多,并且它包含多个到manies。这些属性与allowGenereatedIdInsert相结合可能是根本问题吗?相反,我应该问,有没有人在这种情况下看过这个问题?

更新:永远不要回答问题。我可以使用updateId(...)代替allowGeneratedIdInsert

2 个答案:

答案 0 :(得分:3)

所以我不确定这一点,但在我看来,你试图将一个元素两次插入到具有相同UUID id的表中。例外是说存在约束失败:

IllegalStateException: Could not create data element in dao
    at BaseForeignCollection.add(BaseForeignCollection.java:57)
...
Caused by: SQLiteConstraintException: error code 19: constraint failed

如果你致电foreignCollection.add(...);它与dao.create(...);做同样的事情 - 你不能用同一个对象做这两件事。如果您有一个已由DAO创建的现有对象,并且您想将其与另一个对象关联,则应执行以下操作:

   // associate this object with another
   existingObject.setForeignField(...);
   // now update it in the db
   existingObjectDao.update(existingObject);

您无法将其添加到foreignField的国外集合中。

答案 1 :(得分:1)

我有类似的问题。但它是由使用create而不是createOrUpdate来保存对象引起的。

在更改此应用程序之前卸载应用程序以确保已删除数据库并且不会保留旧行为也很重要。

编辑:createOrUpdate非常耗时。最好只使用大量数据创建。

编辑2:使用TransactionManager.callInTransaction也可以。