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

IllegalArgumentException: Proper ID is not defined for field. when id is in super object #15

Open
blazsolar opened this issue Feb 21, 2014 · 19 comments

Comments

@blazsolar
Copy link

When creating TableInfo only fields of top level class are used. In my case I have id set in super class and i get error because ID field was not found.

Caused by: java.lang.IllegalArgumentException: Proper ID is not defined for field.
        at com.tojc.ormlite.android.framework.TableInfo.<init>(TableInfo.java:109)
        at com.tojc.ormlite.android.framework.MatcherController.addTableClass(MatcherController.java:212)
        at com.tojc.ormlite.android.framework.MatcherController.add(MatcherController.java:87)

It should also check for fields in all super classes.

@rodriamaro
Copy link

For me, this is caused by proguard.. and I don't know how to pass it

@jakenjarvis
Copy link
Owner

Thank you for reporting! I plan to check it.

@jakenjarvis
Copy link
Owner

Hi @blazsolar,
Please give up this. ORMLite also do not support inheritance class apparently.

Please refer to this.

I was also confirmed source code of ORMLite, but there was no significant difference in the acquisition method.

getAnnotation does not seem to work well...(Argument of the annotation can not be read.)
I think Gray Watson gave up the implementation for this reason.

Experimental results of me: Branch 'Issue15'
https://github.com/jakenjarvis/Android-OrmLiteContentProvider/tree/Issue15

@jakenjarvis
Copy link
Owner

Hi @phantomis
Perhaps, it is a different problem... If you do not set properly, the annotation will get deleted.

@suntehnik
Copy link

For me the reason of this exception is different.
I have a model class
@databasetable()
@DefaultContentUri(authority = "co.wecommunicate", path = "group")
@DefaultContentMimeTypeVnd(name = "co.wecommunicate.provider", type = "group")
public class Group {
@DatabaseField(id = true, columnName=BaseColumns._ID)
public long id;

My ID field is not generated locally and thus I don't use "generatedId=true".
This is the reason why I get the same exception.

@jakenjarvis
Copy link
Owner

@suntehnik
oops, sorry. What you pointed out is another issue. Please refer to the #11
This thread is a topic of when using inheritance class.

@renaudcerrato
Copy link

This is crap! OrmLite do supports @DatabaseField on superclasses, and properly detects them.

You only need to add 2 lines to support them into your TableInfo class:

diff --git a/src/com/tojc/ormlite/android/framework/TableInfo.java b/src/com/tojc/ormlite/android/framework/TableInfo.java
index 9a66f58..5064e75 100644
--- a/src/com/tojc/ormlite/android/framework/TableInfo.java
+++ b/src/com/tojc/ormlite/android/framework/TableInfo.java
@@ -74,6 +74,7 @@ public class TableInfo implements Validity {
         SortedMap<Integer, String> defaultSortOrderMap = new TreeMap<Integer, String>();

         this.idColumnInfo = null;
+        while(tableClassType != null) {
             for (Field classfield : tableClassType.getDeclaredFields()) {
                 if (classfield.isAnnotationPresent(DatabaseField.class)) {
                     classfield.setAccessible(true); // private field accessible
@@ -110,6 +111,8 @@ public class TableInfo implements Validity {

                 }
             }
+            tableClassType = tableClassType.getSuperclass();
+        }

         if (this.idColumnInfo == null) {
             // @DatabaseField(columnName = _ID, generatedId = true)

Or you can download my TableInfo here.

@jakenjarvis
Copy link
Owner

@nono240
Oh, I didn't have that idea! thanks. I was trying to access from a subclass in the field of the superclass.
I have not yet tried your code, but would I implement it in the next version(Ver1.0.5).

@renaudcerrato
Copy link

@jakenjarvis : my code was only a proof of concept. You'll probably have to slightly improve your code to correctly handle fields visibility as ormlite do: you must ignore private fields from superclasses.

@jakenjarvis
Copy link
Owner

@nono240 We should read all fields where a @DatabaseField annotation was specified. So I judged, there is no need to ignore a private field. I think your concept is not wrong. :)

@renaudcerrato
Copy link

renaudcerrato commented Feb 28, 2015 via email

@jakenjarvis
Copy link
Owner

He said:

private C cfield;

Will be ignored by ORMLite by default.
The reason is there is no annotation given for the cfield. If you don't specify annotation @DatabaseField for an attribute, that will be ignored.

and

ORMLite by default investigates all base class fields and will find the fields that have annotations.

That's Access level modifiers does not matter.(Of course, the private fields are ignored by default. However, We should read all fields where a @DatabaseField annotation was specified.)
I have judged properly @DatabaseField annotation.

    while(targetTableClassType != null) {
        for (Field classfield : targetTableClassType.getDeclaredFields()) {
            if (classfield.isAnnotationPresent(DatabaseField.class)) {

@renaudcerrato
Copy link

renaudcerrato commented Mar 1, 2015 via email

@renaudcerrato
Copy link

Any update on this?

@jakenjarvis
Copy link
Owner

@renaudcerrato Sorry and thanks for waiting. I for a while, was very busy. I during the holidays of several days, worked on this project.

Result of verifying the Superclass of ORMLite:
OrmLite is not ignore private fields on superclasses. All of the fields that @DatabaseField Annotation has been added, ORMLite will treat it as a valid column.

The reason is because the test code of testDoORMLiteCanBeAccessToThePrivateMembersOfSuperclass() has been finish successfully.

Also, I was searching for Modifier.isPrivate from within the source code of ORMLite, I could not find it. Field is required Modifier.isPrivate is in order to determine whether it is private. For this reason, I was convinced that it is not aware of the access modifier in ORMLite.

Then, I have uploaded the 1.0.5-SNAPSHOT. If possible, please try using. :)

@renaudcerrato
Copy link

1.0.5-SNAPSHOT sounds fine =) Any official release?

@thorinii
Copy link

Hey mate - any chance of a release?

@psamim
Copy link

psamim commented Dec 6, 2015

Waiting for official release of this.
Thanks

@alois-git
Copy link

Might also be because you didn't use a column name containing _ID like this :

@DatabaseField(columnName = BaseColumns._ID, id = true)

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

No branches or pull requests

8 participants