Invalid limitation for Android Room FOREIGN KEY

I am trying to create and implement a folder tree structure in Android SQLite using the Android Persistence (ORM) that Google introduced in I / O 2017. In my design, a folder may contain other folders and files. Here are my codes for the folder and file:

File model:

@Entity(tableName = "files", foreignKeys = @ForeignKey(entity = Folder.class,
    parentColumns = "id",
    childColumns = "parent_id",
    onDelete = CASCADE))
public class File {
    @PrimaryKey(autoGenerate = true)
    private int id;

    private String title;
    private Date creationDate;

    @ColumnInfo(name = "parent_id")
    public int parentId;

    //here setters and getters skipped but exist in original code
}

And here is the folder code:

@Entity(tableName = "folders", foreignKeys = @ForeignKey(entity = Folder.class,
    parentColumns = "id",
    childColumns = "parent_id",
    onDelete = CASCADE,onUpdate = SET_NULL))
public class Folder {
    @PrimaryKey(autoGenerate = true)
    private int id;

    private String name;

    @ColumnInfo(name = "parent_id")
    private int parentId;
}

Who has the foreign key in the column Identifier for the parent.

and here is FolderDAO:

@Dao
public interface FolderDAO {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    public void insertFolder(Folder... folders);

    @Update
    public void updateFolder(Folder... folders);


    @Delete
    public void deleteFolders(Folder... folders);

    @Query("SELECT * FROM folders")
    List<Folder> getAll();

    @Query("SELECT * FROM folders WHERE id IN (:folderIds)")
    List<Folder> loadAllByIds(int[] folderIds);
}

But when I create a folder object and try to insert it:

AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            Folder folder = new Folder();
            folder.setName("All");

            DatabaseInstance.getInstance(getApplicationContext()).folderDAO().insertFolder(folder);

        }
    });

get this error:

FOREIGN KEY constraint failed

         --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
              Process: sahraei.hamidreza.com.note, PID: 1835
              android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)
                  at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
                  at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:782)
                  at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
                  at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
                  at android.arch.persistence.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:80)
                  at android.arch.persistence.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:80)
                  at sahraei.hamidreza.com.note.DAO.FolderDAO_Impl.insertFolder(FolderDAO_Impl.java:80)
                  at sahraei.hamidreza.com.note.ItemListActivity$1.run(ItemListActivity.java:62)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
                  at java.lang.Thread.run(Thread.java:818)

Does anyone know what is wrong or suggest another project for my project table?

+10
source share
2 answers

, , int. , ORM, - .

, Category, UUID :

/***
 Copyright (c) 2017 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain  a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.
 */

package com.commonsware.android.room.dao;

import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.Ignore;
import android.arch.persistence.room.Index;
import android.arch.persistence.room.PrimaryKey;
import java.util.UUID;
import static android.arch.persistence.room.ForeignKey.CASCADE;

@Entity(
  tableName="categories",
  foreignKeys=@ForeignKey(
    entity=Category.class,
    parentColumns="id",
    childColumns="parentId",
    onDelete=CASCADE),
  indices=@Index(value="parentId"))
public class Category {
  @PrimaryKey
  public final String id;
  public final String title;
  public final String parentId;

  @Ignore
  public Category(String title) {
    this(title, null);
  }

  @Ignore
  public Category(String title, String parentId) {
    this(UUID.randomUUID().toString(), title, parentId);
  }

  public Category(String id, String title, String parentId) {
    this.id=id;
    this.title=title;
    this.parentId=parentId;
  }
}

DAO:

@Query("SELECT * FROM categories WHERE parentId IS NULL")
Category findRootCategory();

@Query("SELECT * FROM categories WHERE parentId=:parentId")
List<Category> findChildCategories(String parentId);
+8

, , parentColumns , , , uuid, Kotlin , :

MyClass{
    //Don't do this
    @PrimaryKey(autoGenerate = true)
    var uuid: String = UUID.randomUUID()
}

, .

0

All Articles