【问题标题】:Trouble with @ForeignKey and 3 entities@ForeignKey 和 3 个实体的问题
【发布时间】:2019-04-25 09:28:31
【问题描述】:

我在使用 Room 时遇到了 @ForeignKey 的问题。

我有 3 个实体:位置、用户、汽车。

一个位置可以有一个用户。
一个位置可以拥有一辆车。
一个用户可以有多个位置。
一辆车可以有多个位置(不同的用户)。

我有一份汽车清单。当我在其中一个上向左滑动时,我可以创建一个新位置。

我有两种形式,一种用于创建新用户(此新用户被发送到 Spinner 到 Location 的表单中),另一种用于创建新位置。 如前所述,在位置中,我有一个用户微调器。在创建新用户时,我首先将其保存,然后将其发送到 Location。

当我保存我的位置时,我会返回我的汽车列表,当我向右滑动时,我可以看到与这辆车相关的位置列表。

所以,当我首先添加一个新用户(我们称之为 Tom),然后使用这些新用户创建一个新位置时,它可以完美运行。我可以在向右滑动时看到这个位置,一切都很好。

当我添加第二个新用户(我们称之为 Jerry)时,它会被发送到 Spinner,我可以填写我的位置表单。但是当我尝试保存此表单时,出现外键错误(代码 787)。

你能帮忙吗?我真的不明白如何保存汤姆的位置,但不知道杰瑞的位置(请不要让杰瑞一个人......)

我检查了这些解决方案(以及许多其他..),但似乎没有人和我有同样的问题:

Android Room FOREIGN KEY constraint failed (code 787)
How to avoid room foreign key error - constraint failed (code 787)

位置.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;
    }

汽车.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;
    }

用户.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)

【问题讨论】:

    标签: android sql database foreign-keys android-room


    【解决方案1】:

    几个小时后,我找到了答案。

    答案在 Location 的构造函数中。

    当我创建构造函数时,我有以下参数: dateStart, dateEnd, userId, carId

    当我在其他地方初始化位置时,我会切换 userId 和 carId 的值... 它永远无法工作。

    如果有人来看这篇文章,并且您的代码与我的非常相似,请检查您的初始化 :)。

    Ps:杰瑞找到汤姆回来了 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多