realm / realm-java

Realm is a mobile database: a replacement for SQLite & ORMs
http://realm.io
Apache License 2.0
11.46k stars 1.75k forks source link

Field annotated as @Ignored is not ignored on annotation processing #6368

Open olmur opened 5 years ago

olmur commented 5 years ago

Goal

Compile project

Actual Results

error: Field "status" of type "UserStatus" is not supported.

Steps & Code to Reproduce

Realm class:

@RealmClass
open class AppUserRealm : RealmModel, ConvertableToModel<AppUserModel> {
 ...
    private var statusStr: String = UserStatus.ACTIVE.name

    @Ignore
    var status: UserStatus = UserStatus.ACTIVE
        get() = RealmUtils.enumValueOf(field, statusStr)!!
        set(value) {
            field = value
            statusStr = value.name
        }
...
}

UserStatus is an enum.

Error happens in time of kapt processing.

Gradle file plugins block:

plugins {
    id "com.android.library"
    id "kotlin-android"
    id "kotlin-android-extensions"
    id "kotlin-kapt"
    id "realm-android"
}

Version of Realm and tooling

Realm version(s): 5.8.0

Realm Sync feature enabled: No

Android Studio version: 3.2.1

Android Build Tools version: 28.0.3

Gradle version: 4.10.1

Which Android version and device(s): all

Zhuinden commented 5 years ago

Have you tried @field:Ignore?

olmur commented 5 years ago

Have you tried @field:Ignore?

yes, but no results

cvoronin commented 5 years ago

@olmur What version of Kotlin do you use? I have got the very same problem after switching from 1.2.27 to 1.3.11. It seems to be a kapt problem, the corresponding field in java-generated file is not annotated with @Ignore. This problem I see only when var/val field has get() implementation.

olmur commented 5 years ago

Yeah, the issue happening on 1.3.11 when field has getter also. I made a workaround but that's sad :(

patelnishantk commented 5 years ago

Was facing similar error. Compilation failed stating error mentioned above along with a warning: 'Unclosed files for the types '[io.realm.....RealmProxy]'; these types will not undergo annotation processing'. I noticed that the RealmProxy file generated for my RealmObject was literally unclosed. i.e. with partial generated code.

In my case, attribute with @Ignore annotation had a custom getter/setter. However, the setter was redundant and hence not necessary. Removing the setter fixed the problem. But it is weird since it worked fine till now and only failed after upgrading gradle wrapper, gradle plugin and kotlin version. Also weird is why it fails for custom setter and not the getter.

Gradle wrapper: 5.1.1 Gradle plugin: 3.3.0 Kotlin: 1.3.11 Realm: 5.9.0

MoBo commented 5 years ago

Any updates? Unfortunately Kotlin 1.3 is required when you want to use Gradle plugin 3.3.0

yu2z commented 5 years ago

Same issue. Unclosed files for the types '[]'; these types will not undergo annotation processing

Gradle wrapper: 4.6, 4.10.1, 5.1.1 Gradle plugin: 3.3.0 Kotlin: 1.3.20, 1.3.21 Realm: 5.8.0, 5.9.0

@Zhuinden can you give some advice or estimates?

Zhuinden commented 5 years ago

@yu2z I'm not a Realm member and I am not working on Realm and therefore I certainly won't know anything about estimates; but my only guess would be to try @field:Ignore @get:Ignore @set:Ignore and if it still doesn't work then... well, try something else? You could try marking it @Transient.

monarezio commented 5 years ago

@Zhuinden Hi I tried marking the properties @Transient, which also did not solve the problem.

Gradle: 4.10.1 Kotlin: 1.3.11 Realm: 5.8.0

Zhuinden commented 5 years ago

Yeah, no idea from me.

@cmelchior ?

cmelchior commented 5 years ago
open class Test: RealmObject() {

    enum class MyEnum {
        Test
    }

    private var strField: String = MyEnum.Test.name

    var enumField: MyEnum
        get() = MyEnum.values().first { it.name == strField }
        set(value) { strField = value.name }
}

This works for me in Kotlin 1.3.21

In the above case the enumField do not have a backing field (which is what trips Realm up), so no @Ignore annotation is needed.

It is because you refer to the field that causes Kotlin to create the backing field which is picked up by the Realm annotation processor

cmelchior commented 5 years ago

I couldn't find a way to set an annotation on the backing field itself in the Kotlin documentation, so I don't know if that is possible.

In any case, trying to store a quick reference to the enum value is going to bite you as the RealmObject is live, so the underlying String value for the enum can change while the cached value will not. So I would not recommend that.

I suspect this is something we would want to document in the Kotlin section of our docs as this is rather non-obvious if you don't know the intimate details of both Kotlin and Realm.

monarezio commented 5 years ago

@cmelchior I think that's a reasonable solution, I would suggest adding into the doc (sorry if it already is). I guess there is not a neater way of solving this issue.

Cheers!