Android 工作室和房间 - 外键和约束失败
Android studio and Room - Foreign keys and constraint failed
我正在尝试使用 Room 数据库制作一个应用程序。我有一只 table 鸟和一只 table 家庭。 (一对多关系)。
@Entity(tableName ="bird",
foreignKeys =
@ForeignKey(entity = Family.class,
parentColumns = "id",
childColumns = "familyId",
onDelete = CASCADE),
indices = {@Index("familyId")})
public class Bird {
@PrimaryKey(autoGenerate = true)
private int id;
private int familyId;
private String name;
private String family;
private String description;
private String biology;
public Bird(@NonNull String name, @NonNull String family, String description, String biology){
this.name = name;
this.family = family;
this.description= description;
this.biology = biology;
this.familyId = familyId;
}
@Entity(tableName = "family")
public class Family {
@PrimaryKey(autoGenerate = true)
private int id;
private String family;
public Family(@NonNull String family)
{
this.family = family;
}
每次我尝试 运行 我的鸟类列表(在实施家庭实体之前工作正常)时,没有任何显示,当我尝试使用 @Insert 查询添加新鸟类时,我被击中通过这个:
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:879)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
at com.example.room.Dao_Impl.insertBird(Dao_Impl.java:115)
at com.example.room.BirdRepository$InsertBirdAsyncTask.doInBackground(BirdRepository.java:56)
at com.example.room.BirdRepository$InsertBirdAsyncTask.doInBackground(BirdRepository.java:45)
at android.os.AsyncTask.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
你们知道这可能来自哪里吗?
我也是这样填写数据库的吗?
private static void fillWithSartingData(Context context){
Dao dao = getInstance(context).dao();
FamilyDao familyDao = getInstance(context).familyDao();
JSONArray birds = loadJSONArray(context);
JSONArray families = loadJSONArray(context);
try{
for(int i = 0; i< families.length(); i++){
JSONObject familyObj = families.getJSONObject(i);
String family = familyObj.getString("FamilieF");
familyDao.insertFamily(new Family(family));
}
for(int i = 0; i< birds.length(); i++){
JSONObject bird = birds.getJSONObject(i);
String engName = bird.getString("NameEng");
String family = bird.getString("FamilieF");
String description = bird.getString("Description");
String biology = bird.getString("Biologie");
dao.insertBird(new Bird(engName, family, description, biology));
}
} catch (JSONException e){
}
}
谢谢!
亚历克斯
你违反了外键约束"FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)"因为你没有在Bird中设置familyId
class
你必须在 Bird
class 中设置 familyId
才能插入鸟
为此向 bird 构造函数添加一个 familyId
参数,如下所示:
public Bird(@NonNull String name, @NonNull String family, String description, String biology, long familyId){
this.name = name;
this.family = family;
this.description= description;
this.biology = biology;
this.familyId = familyId;
}
insertFamily
in familyDao
应该 return Long(如果它有一个 Family 参数)或 Long Array(如果它有可变参数 Family 参数)然后你从insertFamily
并将其用作 familyId
,如下所示:
for(int i = 0; i< families.length(); i++){
JSONObject familyObj = families.getJSONObject(i);
String family = familyObj.getString("FamilieF");
long familyId = familyDao.insertFamily(new Family(family));// get familyId
for(int i = 0; i< birds.length(); i++){
JSONObject bird = birds.getJSONObject(i);
String engName = bird.getString("NameEng");
String family = bird.getString("FamilieF");
String description = bird.getString("Description");
String biology = bird.getString("Biologie");
dao.insertBird(new Bird(engName, family, description, biology, familyId));// use familyId
}
我正在尝试使用 Room 数据库制作一个应用程序。我有一只 table 鸟和一只 table 家庭。 (一对多关系)。
@Entity(tableName ="bird",
foreignKeys =
@ForeignKey(entity = Family.class,
parentColumns = "id",
childColumns = "familyId",
onDelete = CASCADE),
indices = {@Index("familyId")})
public class Bird {
@PrimaryKey(autoGenerate = true)
private int id;
private int familyId;
private String name;
private String family;
private String description;
private String biology;
public Bird(@NonNull String name, @NonNull String family, String description, String biology){
this.name = name;
this.family = family;
this.description= description;
this.biology = biology;
this.familyId = familyId;
}
@Entity(tableName = "family")
public class Family {
@PrimaryKey(autoGenerate = true)
private int id;
private String family;
public Family(@NonNull String family)
{
this.family = family;
}
每次我尝试 运行 我的鸟类列表(在实施家庭实体之前工作正常)时,没有任何显示,当我尝试使用 @Insert 查询添加新鸟类时,我被击中通过这个:
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:879)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:88)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
at com.example.room.Dao_Impl.insertBird(Dao_Impl.java:115)
at com.example.room.BirdRepository$InsertBirdAsyncTask.doInBackground(BirdRepository.java:56)
at com.example.room.BirdRepository$InsertBirdAsyncTask.doInBackground(BirdRepository.java:45)
at android.os.AsyncTask.call(AsyncTask.java:378)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:289)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
你们知道这可能来自哪里吗?
我也是这样填写数据库的吗?
private static void fillWithSartingData(Context context){
Dao dao = getInstance(context).dao();
FamilyDao familyDao = getInstance(context).familyDao();
JSONArray birds = loadJSONArray(context);
JSONArray families = loadJSONArray(context);
try{
for(int i = 0; i< families.length(); i++){
JSONObject familyObj = families.getJSONObject(i);
String family = familyObj.getString("FamilieF");
familyDao.insertFamily(new Family(family));
}
for(int i = 0; i< birds.length(); i++){
JSONObject bird = birds.getJSONObject(i);
String engName = bird.getString("NameEng");
String family = bird.getString("FamilieF");
String description = bird.getString("Description");
String biology = bird.getString("Biologie");
dao.insertBird(new Bird(engName, family, description, biology));
}
} catch (JSONException e){
}
}
谢谢! 亚历克斯
你违反了外键约束"FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY)"因为你没有在Bird中设置familyId
class
你必须在 Bird
class 中设置 familyId
才能插入鸟
为此向 bird 构造函数添加一个 familyId
参数,如下所示:
public Bird(@NonNull String name, @NonNull String family, String description, String biology, long familyId){
this.name = name;
this.family = family;
this.description= description;
this.biology = biology;
this.familyId = familyId;
}
insertFamily
in familyDao
应该 return Long(如果它有一个 Family 参数)或 Long Array(如果它有可变参数 Family 参数)然后你从insertFamily
并将其用作 familyId
,如下所示:
for(int i = 0; i< families.length(); i++){
JSONObject familyObj = families.getJSONObject(i);
String family = familyObj.getString("FamilieF");
long familyId = familyDao.insertFamily(new Family(family));// get familyId
for(int i = 0; i< birds.length(); i++){
JSONObject bird = birds.getJSONObject(i);
String engName = bird.getString("NameEng");
String family = bird.getString("FamilieF");
String description = bird.getString("Description");
String biology = bird.getString("Biologie");
dao.insertBird(new Bird(engName, family, description, biology, familyId));// use familyId
}