Search code examples
hibernatekotlinjpacollectionshibernate-mapping

Recreating table using JPA, Kotlin and @ElementCollection


I have weird problem. This is my code:

@Table(name = "rank")
@Entity
data class Rank(
        @Id
        private val id: String,

        @Embedded
        private var rankValue: RankValue,

        @ElementCollection
        @CollectionTable(
                name="rank_change",
                joinColumns = [JoinColumn(name = "rank_id")]
        )
        private val set: MutableSet<RankChange>

) {

    fun calculateDifference(loseRank: Rank, rankPolicy: RankPolicy): Double {
        return rankPolicy.calculateRankDifference(rankValue.value, loseRank.rankValue.value)
    }

    fun addChange(difference: Double, now: LocalDateTime, sparringId: String? = null) {
        rankValue = rankValue.apply(difference)
        set.add(RankChange(date = now, value = difference, sparringId = sparringId))
    }
}
@Embeddable
data class RankChange(
        @Column(name = "date")
        private val date: LocalDateTime,

        @Column(name = "value")
        private val value: Double,

        @Column(name = "sparring_id")
        private val sparringId: String? = null
)

When I add element to MutableSet<RankChange> hibernate deletes "rank_change" table and insert row by row. Maybe should I implement equals and hash code contract or use MutableList<T> and add @OrderColumn annotation ? But I really don't need order.


Solution

  • @ElementCollection behaves like unidirectional @OneToMany in that sense it deletes all the rows and inserts elements from the in-memory collection one by one.

    To avoid this you could create a separate entity to hold the elements and make the (@OneToMany - @ManyToOne) relationship bidirectional (with mappedBy on the parent side and @JoinColumn on the child side).