kamikat / moshi-jsonapi

JSON API v1.0 Specification in Moshi.
MIT License
156 stars 34 forks source link

Strange behaviour of object used in an API call #111

Open sterien7 opened 4 years ago

sterien7 commented 4 years ago

I have problems trying to do the following in my app in Kotlin I have 2 objects, User and UserRelationship

import moe.banana.jsonapi2.JsonApi
import moe.banana.jsonapi2.Resource

JsonApi(type = "users")
class User : Resource() {

    @field:Json(name = "related-user-relationships")
    var relatedUserRelationships: HasMany<UserRelationship>? = null

    val relatedUserRelationshipsCollection: List<UserRelationship>?
        get() {
            return relatedUserRelationships?.get(this.document)
        }
}

@JsonApi(type = "user-relationships")
class UserRelationship() : Resource() {
    @field:Json(name = "is-favorite")
    var isFavorite: Boolean = false

    var user: HasOne<User>? = null
    @field:Json(name = "related-user")
    var relatedUser: HasOne<User>? = null

    val userObject: User?
        get() {
            return user?.get(this.document)
        }

    val relatedUserObject: User?
        get() {
            return relatedUser?.get(this.document)
        }
}

The task needed it to search if userA has a relationship with userB and then update it so the code I execute is

var userRelationship = userA.relatedUserRelationshipsCollection?.firstOrNull { it.relatedUserObject?.id == userB.id } ?: UserRelationship()
userRelationship.user = HasOne(userA)
userRelationship.relatedUser = HasOne(userB)
userRelationship.isFavorite = !userRelationship.isFavorite

and after that I execute the http request

@POST("user-relationships")
 fun addUserRelationship(@Body userRelationship: UserRelationship): Observable<UserRelationship>

The request executes without a problem and returns the relationship object. The problem is than now userA.document = null but userB.document is not null

any ideas

sterien7 commented 4 years ago

I came up with an idea. I though what if I had the exact object copied to a new one and I created a method

fun <T : Serializable> deepCopy(obj: T?): T? {
        if (obj == null) return null
        val baos = ByteArrayOutputStream()
        val oos  = ObjectOutputStream(baos)
        oos.writeObject(obj)
        oos.close()
        val bais = ByteArrayInputStream(baos.toByteArray())
        val ois  = ObjectInputStream(bais)
        @Suppress("unchecked_cast")
        return ois.readObject() as T
    }

after using this method in order to create the UserRelationship that I POST to the server, everything worked. So I think it has something to do with retrofit and the way it handles the data sent over HTTP

Is that helpfull?