Я новичок в разработке для Android и пытаюсь создать поездку, в которой много локаций. Создается поездка, затем осуществляется доступ и создается местоположение с использованием trip_id, переданного из предыдущего действия. Я использую LiveData для хранения Списка данных и отображения их в RecyclerView.
Я пробовал многие из опубликованных здесь решений, таких как использование UUID для первичных ключей вместо их автоматической генерации: Ограничение FOREIGN KEY для Android Room не выполнено .
Тем не менее, я все еще получаю ту же ошибку. Так что это оригинальный код, без UUID.
Trip.java
@Entity(tableName = "trip_table",
indices = {@Index(value = {"location_Id"}, unique = true),
@Index(value = {"tripNo"}, unique = true)})
public class Trip {
@PrimaryKey(autoGenerate = true)
@ColumnInfo (name = "location_Id")
private int id;
private String title;
private String description;
private int priority;
private int tripNo;
public Trip(String title, String description, int priority) {
this.title = title;
this.description = description;
this.priority = priority;
}
// getter, setters
Location.java
@Entity(tableName = "location_table",
foreignKeys = @ForeignKey(entity = Trip.class, parentColumns = "tripNo", childColumns = "trip_Id"),
indices = {@Index(value = {"trip_Id"})})
public class Location {
@PrimaryKey(autoGenerate = true)
private int locationId;
@ColumnInfo (name = "trip_Id")
private int tripId;
private String locationName;
@TypeConverters(LatLngConverter.class)
private LatLng latLng;
public Location(int tripId, String locationName, LatLng latLng) {
this.tripId = tripId;
this.locationName = locationName;
this.latLng = latLng;
}
// getter, setters
Создание нового Trip в MainActivity.java.
Trip trip = new Trip(title, description, priority);
tripViewModel.insert(trip);
tripViewModel.updateTripNo();
Передача trip_id к следующему занятию
public void onTripItemClick(Trip trip) {
Intent intent = new Intent(MainActivity.this, viewTripLocations.class);
intent.putExtra(viewTripLocations.EXTRA_TRIP_ID, trip.getId());
Log.d("TRIPINFO", "Trip ID is " + trip.getId()); // D/TRIPINFO: Trip ID is 2
Log.d("TRIPINFO", "Trip No is " + trip.getTripNo()); // D/TRIPINFO: Trip No is 2
startActivity(intent);
}
Это прекрасно работает и отображается в RecyclerView, что позволяет мне щелкнуть по нему, чтобы перейти к следующему занятию: viewTripLocations. java.
После ввода имени и координат LatLng в другом действии метод onActivityResult запускается и возвращается к viewTripLocations.java.
protected void onActivityResult(int requestCode, int resultCode, Intent data)
// codes getting name, latlng
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
int tripId = ((int)(bundle.get(EXTRA_TRIP_ID)));
Location location = new Location(tripId, locationName, locationLatLng);
Log.d("Trip ID is ", "" +tripId); //D/Trip ID used is: 2
Log.d("LOCINFO","Location is " + location.getLocationName() + " ID is " + location.getLocationId() + " REFERENCES Trip " + location.getTripId()); // D/LOCINFO: Location is v ID is 0 REFERENCES Trip 2
locationViewModel.insert(location); //crashes here
Это ошибка, выведенная
D/Trip ID is : 1
D/TRIPINFO: Trip is 23/11/2019 ID is 1
D/LOCINFO: Location is Tokyo ID is 0 REFERENCES Trip 1
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
Process: com.example.TravelPlanner, PID: 9117
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:354)
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:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787 SQLITE_CONSTRAINT_FOREIGNKEY[787])
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:995)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeInsert(FrameworkSQLiteStatement.java:51)
at androidx.room.EntityInsertionAdapter.insert(EntityInsertionAdapter.java:64)
at com.example.travelplanner.LocationDao_Impl.insert(LocationDao_Impl.java:110)
at com.example.travelplanner.LocationRepository$InsertLocationAsyncTask.doInBackground(LocationRepository.java:51)
at com.example.travelplanner.LocationRepository$InsertLocationAsyncTask.doInBackground(LocationRepository.java:42)
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:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
Чтобы добавить, использование DB Browser позволило мне подтвердить вставку Trip с помощью tripViewModel.insert (trip).
Я понимаю, почему происходит ошибка, но не понимаю, как создается объект Trip. заранее
Поскольку я все еще неопытен, я мог бы делать некоторые вещи неправильно, поэтому я был бы признателен за помощь.