robie2011
robie2011

Reputation: 3888

Spring Data Rest one to many JSON Formatting: Use foreign key instead of objects

Im using spring boot with 2.0.0.M6 with kotlin 1.1.51 with org.springframework.boot:spring-boot-starter-data-rest and trying to format output of json.

How can i config. spring rest data so that it will output/accept foreign key instead of object with href in a ManyToOne-Relationship?

sample model with foreign key language_id (kotlin):

@Entity
data class Song (
        @Column
        var title: String,

        @Column
        var songTypeId: Int,

        @OneToMany(mappedBy = "song")
        var mastersheets: Set<Mastersheet> = setOf<Mastersheet>()


) : UpdateableBaseEntity() {

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name = "language_id", nullable = false)
        lateinit var language: Language

        @ManyToOne()
        @JoinColumn(name = "artist_id", nullable = false)
        lateinit var artist: Artist
}

output is something like:

{
  "_embedded" : {
    "songs" : [ {
      "title" : "Hello World",
      "songTypeId" : 1,
      "insertDate" : "2018-09-06T07:25:14.307+0000",
      "updateDate" : null,
      "_links" : {
        "self" : {
          "href" : "http://localhost/songs/1"
        },
        "song" : {
          "href" : "http://localhost/songs/1"
        },
        "artist" : {
          "href" : "http://localhost/songs/1/artist"
        },
        "mastersheets" : {
          "href" : "http://localhost/songs/1/mastersheets"
        },
        "language" : {
          "href" : "http://localhost/songs/1/language"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost/songs"
    },
    "profile" : {
      "href" : "http://localhost/profile/songs"
    }
  }
}

Note: I also tried this configuration

@Bean
fun repositoryRestConfigurer(): RepositoryRestConfigurer {
    return object : RepositoryRestConfigurerAdapter() {
        override fun configureRepositoryRestConfiguration(config: RepositoryRestConfiguration?) {
            config!!.exposeIdsFor(Language::class.java)
        }
    }
}

Upvotes: 1

Views: 841

Answers (1)

robie2011
robie2011

Reputation: 3888

I found my solution here https://stackoverflow.com/a/38165158/2248405

With SpringExpression Language (SpEL) it is possible to have everything in the same object:

@Projection(name = "fullDetails", types = arrayOf(Song::class))
interface SongsFullDetailsProjection {
    fun getId(): Long
    fun getTitle(): String

    @Value("#{target.getArtist()?.getId()}")
    fun getArtistId(): Long?

    @Value("#{target.getSongType()?.getId()}")
    fun getSongTypeId(): Long?


    @Value("#{target.getLanguage()?.getId()}")
    fun getLanguageId(): Long?

}

Upvotes: 1

Related Questions