Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OneToOne - Couldn't find referenced element #209

Closed
ghost opened this issue Jun 27, 2016 · 10 comments
Closed

OneToOne - Couldn't find referenced element #209

ghost opened this issue Jun 27, 2016 · 10 comments
Labels

Comments

@ghost
Copy link

ghost commented Jun 27, 2016

I have recently come back to my project after being too busy to work on it for a while, and I upgraded requery to the latest version (beta23), and I am now having an issue with a OneToOne relationship that I didn't previously have.

I had a read through the changelog and didn't seem to find anything which would have changed that I needed to update so I'm not entirely sure what is wrong.

My entities are as follows.

@Entity(stateless = true)
public abstract class AbstractEvent {
    // ...

    @ForeignKey
    @OneToOne(mappedBy = "owner")
    protected Staff staff;

    // ...
}
@Entity(stateless = true)
public abstract class AbstractStaff {
    // ...

    @OneToOne(mappedBy = "staff")
    protected Event owner;
}

When building I get the following warnings, both listed under the AbstractEvent file.

Warning: Couldn't find referenced element  for package.name.data.model.Event.staff
Warning: Couldn't find referenced element  for package.name.data.model.Event.staff

When trying to save something to the database, I get the following in the logcat.

java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object io.requery.util.function.Supplier.get()' on a null object reference
     at io.requery.sql.Attributes.get(Attributes.java:38)
     at io.requery.sql.EntityWriter.bindParameters(EntityWriter.java:352)
     at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:67)
     at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:55)
     at io.requery.query.BaseScalar.value(BaseScalar.java:49)
     at io.requery.sql.EntityWriter.insert(EntityWriter.java:452)
     at io.requery.sql.EntityWriter.cascadeWrite(EntityWriter.java:926)
     at io.requery.sql.EntityWriter.updateInverseAssociation(EntityWriter.java:782)
     at io.requery.sql.EntityWriter.updateAssociations(EntityWriter.java:665)
     at io.requery.sql.EntityWriter.insert(EntityWriter.java:454)
     at io.requery.sql.EntityWriter.insert(EntityWriter.java:410)
     at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:209)
     at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:199)
     at io.requery.rx.SingleEntityStoreFromBlocking$1.get(SingleEntityStoreFromBlocking.java:87)
     at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:34)
     at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:23)
     at rx.Single$1.call(Single.java:94)
     at rx.Single$1.call(Single.java:74)
     at rx.Single.subscribe(Single.java:1822)
     at rx.Single.subscribe(Single.java:1899)
     at rx.Single$19$1.call(Single.java:1954)
     at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
     at rx.internal.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(ExecutorScheduler.java:104)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
     at java.lang.Thread.run(Thread.java:818)
@npurushe
Copy link
Contributor

Can you try a clean and rebuild? Looks like AbstractStaff isn't being processed. Creating a simple app with just

@Entity(stateless = true)
public class AbstractStaff {

    @Key
    @Generated
    protected int id;

    @OneToOne(mappedBy = "staff")
    protected Event owner;
}

@Entity(stateless = true)
public class AbstractEvent {

    @Key @Generated
    protected int id;

    @ForeignKey
    @OneToOne(mappedBy = "owner")
    protected Staff staff;
}

compiles ok. Also if you gradle build are there any errors in the output?

@ghost
Copy link
Author

ghost commented Jun 29, 2016

I did try cleaning and rebuilding which, as well as deleting the entire build folder, disabling instant run, and cleaning app data on the phone, but I still get the same warnings on build.

Another one I noticed, if this is at all helpful.
Note: C:\somepath\package\name\data\model\Event.java uses unchecked or unsafe operations.

Running a gradle build only seems to bring up some lint errors.

There are two other annotation processors in the project, Dagger2 and ButterKnife 8, I don't know if there could potentially be something conflicting with them.

@npurushe
Copy link
Contributor

Ok looks like no build errors. Looks like this can happen if you are missing a key in one of the entities. Can you provide the whole entity definition?

@ghost
Copy link
Author

ghost commented Jun 30, 2016

Ah yes, I was missing a key in one of them, I added that in, however now I appear to be getting a different error.

@Entity(stateless = true)
public abstract class AbstractEvent {
    @Key
    @Generated
    protected int id;

    protected String code;

    protected String startTime;

    protected String endTime;

    @SerializedName("day")
    protected String dayName;

    protected String name;

    protected String roomCode;

    protected String roomDescription;

    protected String type;

    protected String colour;

    @ForeignKey
    @OneToOne(mappedBy = "owner")
    protected Staff staff;

    @Column
    @Convert(IntegerListConverter.class)
    protected ArrayList<Integer> weeks;
}
@Entity(stateless = true)
public abstract class AbstractStaff {
    @Key
    @Generated
    protected int id;

    protected String firstName;

    protected String surname;

    protected String email;

    protected String salutation;

    protected String department;

    protected String jobTitle;

    protected String timetableName;

    @OneToOne(mappedBy = "staff")
    protected Event owner;
}

And in the logcat I am getting the following exception.

io.requery.sql.StatementExecutionException: Exception executing statement: insert into Event (code, colour, dayName, endTime, name, roomCode, roomDescription, staff, startTime, studentOwner, type, weeks) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:74)
    at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:55)
    at io.requery.query.BaseScalar.value(BaseScalar.java:49)
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:452)
    at io.requery.sql.EntityWriter.cascadeWrite(EntityWriter.java:926)
    at io.requery.sql.EntityWriter.updateInverseAssociation(EntityWriter.java:782)
    at io.requery.sql.EntityWriter.updateAssociations(EntityWriter.java:665)
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:454)
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:410)
    at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:209)
    at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:199)
    at io.requery.rx.SingleEntityStoreFromBlocking$1.get(SingleEntityStoreFromBlocking.java:87)
    at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:34)
    at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:23)
    at rx.Single$1.call(Single.java:94)
    at rx.Single$1.call(Single.java:74)
    at rx.Single.subscribe(Single.java:1822)
    at rx.Single.subscribe(Single.java:1899)
    at rx.Single$19$1.call(Single.java:1954)
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
     at rx.internal.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(ExecutorScheduler.java:104)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
 Caused by: java.sql.SQLIntegrityConstraintViolationException: android.database.sqlite.SQLiteConstraintException: FOREIGN KEY constraint failed (code 787)
    at io.requery.android.sqlite.BaseConnection.throwSQLException(BaseConnection.java:69)
    at io.requery.android.sqlite.SqlitePreparedStatement.executeUpdate(SqlitePreparedStatement.java:164)
    at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:69)
    at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:55) 
    at io.requery.query.BaseScalar.value(BaseScalar.java:49) 
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:452) 
    at io.requery.sql.EntityWriter.cascadeWrite(EntityWriter.java:926) 
    at io.requery.sql.EntityWriter.updateInverseAssociation(EntityWriter.java:782) 
    at io.requery.sql.EntityWriter.updateAssociations(EntityWriter.java:665) 
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:454) 
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:410) 
    at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:209) 
    at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:199) 
    at io.requery.rx.SingleEntityStoreFromBlocking$1.get(SingleEntityStoreFromBlocking.java:87) 
    at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:34) 
    at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:23) 
    at rx.Single$1.call(Single.java:94) 
    at rx.Single$1.call(Single.java:74) 
    at rx.Single.subscribe(Single.java:1822) 
    at rx.Single.subscribe(Single.java:1899) 
    at rx.Single$19$1.call(Single.java:1954) 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
    at rx.internal.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(ExecutorScheduler.java:104) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
    at java.lang.Thread.run(Thread.java:818) 
 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 io.requery.android.sqlite.SqlitePreparedStatement.executeUpdate(SqlitePreparedStatement.java:160)
    at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:69) 
    at io.requery.sql.EntityUpdateOperation$1.evaluate(EntityUpdateOperation.java:55) 
    at io.requery.query.BaseScalar.value(BaseScalar.java:49) 
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:452) 
    at io.requery.sql.EntityWriter.cascadeWrite(EntityWriter.java:926) 
    at io.requery.sql.EntityWriter.updateInverseAssociation(EntityWriter.java:782) 
    at io.requery.sql.EntityWriter.updateAssociations(EntityWriter.java:665) 
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:454) 
    at io.requery.sql.EntityWriter.insert(EntityWriter.java:410) 
    at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:209) 
    at io.requery.sql.EntityDataStore.insert(EntityDataStore.java:199) 
    at io.requery.rx.SingleEntityStoreFromBlocking$1.get(SingleEntityStoreFromBlocking.java:87) 
    at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:34) 
    at io.requery.rx.SingleOnSubscribeFromSupplier.call(SingleOnSubscribeFromSupplier.java:23) 
    at rx.Single$1.call(Single.java:94) 
    at rx.Single$1.call(Single.java:74) 
    at rx.Single.subscribe(Single.java:1822) 
    at rx.Single.subscribe(Single.java:1899) 
    at rx.Single$19$1.call(Single.java:1954) 
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 
    at rx.internal.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.run(ExecutorScheduler.java:104) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
    at java.lang.Thread.run(Thread.java:818)

@npurushe
Copy link
Contributor

npurushe commented Jul 1, 2016

From the exception you have a link that maybe invalid, e.g could be studentOwner which doesn't match the definition you have. Did you start from a fresh database or are you using an old one before the key column was added? Also if you use a stateless entity you should manually insert the entity that the even is referencing first instead of relying on the cascade

@ghost
Copy link
Author

ghost commented Jul 1, 2016

Thanks for your help so far.

I had made a mistake on the Event entity, the studentOwner should have been ManyToOne not OneToOne, however after changing that I still seem to be getting that same exception.

I have cleared out the app's data so the database should be fresh.

The Student entity is as follows.

@Entity(stateless = true)
public abstract class AbstractStudent {
    @Key
    @SerializedName("_id")
    protected String username;

    protected String courseId;

    protected String courseLength;

    protected String firstName;

    protected String surname;

    @OneToMany(mappedBy = "studentOwner", cascade = {CascadeAction.DELETE, CascadeAction.SAVE})
    protected List<Event> events;
}

That is being populated through GSON, and being inserted using mDataStore.insert(student).toObservable();.

@npurushe
Copy link
Contributor

npurushe commented Jul 5, 2016

Which order are you inserting the entities? The core of your issue is you have an invalid id studentOwner value in your Event, meaning that entity is either not inserted in the table or the entity is invalid as referenced to it.

@ghost
Copy link
Author

ghost commented Jul 10, 2016

So I was just inserting the student and nothing else as I thought that would also insert all of the events.

It appears that all of the studentOwners are null for the Events, I assume this is because they are being populated from GSON?

So when inserting I tried something like

for (Event event : student.getEvents()) {
    event.setStudentOwner(student);
}
return mDataStore.insert(student).toObservable();

But I still appear to be getting the same error.

@npurushe
Copy link
Contributor

I would try inserting the student first, attaching all the events to it and then updating it

@ghost ghost closed this as completed Jul 15, 2016
@developpef
Copy link

I would try inserting the student first, attaching all the events to it and then updating it

That was the solution for me... Quite strange though that Requery can't create a complete objects bunch...

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants