使用Room时,@ ForeignKey出现问题。
我有3个实体:位置,用户,汽车。
一个位置可以有一个用户。
一个地点可以有一辆车。
一个用户可以有多个位置。
一辆汽车可以有多个位置(具有不同的用户)。
我有汽车清单。当我向左滑动其中一个时,我可以创建一个新位置。
我有两种形式,一种是创建新用户(此新用户被发送到微调器到位置的表单中),另一种是创建新位置。 如前所述,在位置中,我有一个用户微调器。创建新用户时,首先保存它,然后将其发送到“位置”。
保存位置后,我会回到汽车列表上,向右滑动时,会看到与此车相关的位置列表。
因此,当我首先添加一个新用户(我们将其称为Tom),然后添加具有这些新用户的新位置时,它的工作原理非常完美。我可以在向右滑动时看到此位置,一切都很好。
当我添加第二个新用户(我们称其为Jerry)时,该用户将被发送到微调框,然后我可以填写我的位置表格。但是,当我尝试保存此表单时,出现了外键错误(代码787)。
可以帮忙吗?我真的不知道如何保存汤姆的位置,但不知道如何保存杰里的位置(请不要让杰里一个人呆着……)
我检查了这些解决方案(以及许多其他方法。),但是似乎没有人遇到与我相同的问题:
Android Room FOREIGN KEY constraint failed (code 787)
How to avoid room foreign key error - constraint failed (code 787)
Location.java
@Entity(tableName = "location", foreignKeys = {
@ForeignKey(
onDelete = ForeignKey.CASCADE,
entity = User.class,
parentColumns = "id",
childColumns = "userId"),
@ForeignKey(
onDelete = ForeignKey.CASCADE,
entity = Car.class,
parentColumns = "id",
childColumns = "carId")
})
public class Location implements Parcelable{
@PrimaryKey (autoGenerate = true)
private int id;
private Date dateStart;
private Date dateEnd;
private int userId;
private int carId;
public Location(Date dateStart, Date dateEnd, int userId, int carId) {
this.dateStart = dateStart;
this.dateEnd = dateEnd;
this.userId = userId;
this.carId = carId;
}
Car.java
@SuppressWarnings(RoomWarnings.PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED)
@Entity(tableName = "car")
public class Car implements Parcelable{
@PrimaryKey(autoGenerate = true)
private int id;
private String immatriculation;
private float price;
private boolean isRestore;
private String imagePath;
private String model;
@Embedded
private CarType carType;
public Car(int id, String immatriculation, float price, boolean isRestore, String imagePath, String model, CarType carType) {
this.id = id;
this.immatriculation = immatriculation;
this.price = price;
this.isRestore = isRestore;
this.imagePath = imagePath;
this.model = model;
this.carType = carType;
}
User.java
@Entity(tableName = "user")
public class User implements Parcelable {
@PrimaryKey(autoGenerate = true)
private int id;
private String name;
private String firstname;
private String phoneNumber;
private String email;
public User(String name, String firstname, String phoneNumber, String email) {
this.name = name;
this.firstname = firstname;
this.phoneNumber = phoneNumber;
this.email = email;
}
我收到此错误
04-25 08:51:30.312 10581-10709/fr.eni.lokacar E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
Process: fr.eni.lokacar, PID: 10581
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: 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:50)
at android.arch.persistence.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
at fr.eni.lokacar.dao.LocationDAO_Impl.insert(LocationDAO_Impl.java:112)
at fr.eni.lokacar.repository.LocationRepository$AsyncInsert.doInBackground(LocationRepository.java:71)
at fr.eni.lokacar.repository.LocationRepository$AsyncInsert.doInBackground(LocationRepository.java:65)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
答案 0 :(得分:0)
几个小时后,我找到了答案。
答案在Location的构造函数中。
创建构造函数时,我具有以下参数: dateStart,dateEnd,userId,carId
当我在其他地方初始化Location时,我切换了userId和carId的值... 它永远都行不通。
如果有人来这篇文章,并且您的代码与我的代码非常相似,请检查您的初始化:)。
Ps:Jerry找到Tom回来了:)