OneToMany
mapping will connect one Box
with many Colors
. Therefore, each Color
needs to point to a Box
, so each Color
has a foreign key referencing the primary key of Box
(of Int
type).

@OneToMany as an owning side
In your mapping, you should use a single join column since this join column will be placed in the color
table:
@Entity
@Table(name = "box")
data class Box(
@Id
var id: Int = 0,
...
@OneToMany(cascade = [CascadeType.ALL])
@JoinColumn(name = "box_id", referencedColumnName = "id")
var colors: MutableList<Color> = mutableListOf()
)
You can check-out the working sample (Kotlin and Java) in my github repo.
@OneToMany as an inverse (mapped-by) side
Database perspective
@OneToMany
as an owning side and @OneToMany
as an inverse side (with a complimentary mandatory @ManyToOne
) produce the same database schema - a foreign key on the color
table. That's why @JoinColumn
annotation looks the same in both cases, no matter which side you place it on - the goal is to produce a foreign key on the many
side.
Application perspective
The difference in 'owning-side' is in an application perspective. JPA/hibernate saves the relationships only from the owning side.
So, if you change the owning side, you must set up this side (attribute) in your application code. In this case, you must set up Box
in Color
, otherwise, JPA/hibernate will not create a relationship (even though you added your Colors
to Box
). Moreover, it will not raise any exception, just the relationship will not be created. Next time, you will retrieve your Box
from a database, the Color
list will be empty.
You can check-out the working samples and see the difference in ownership in my github repo.
@Entity
@Table(name = "box")
data class Box(
@Id
var id: Int = 0,
...
@OneToMany(cascade = [CascadeType.ALL], mappedBy="box")
var colors: MutableList<Color> = mutableListOf(),
)
@Entity
@Table(name = "color")
data class Color(
@EmbeddedId
var colorId: ColorId? = null,
// the owning side is changed, therefore you MUST set the box in Color
// otherwise the relationship in a database will not be saved (!)
@ManyToOne
@JoinColumn(name = "box_id")
var box: Box? = null
) : Serializable
Other possible problems
Since you struggle with a OneToMany
relationship, it might be useful for you to consider some other possible problems in this model.
Locale non-insertable and non-updatable
Another problem, you may encounter, is saving locale
in ColorId
as you marked it as non-insertable
and non-updatable
. If this is on purpose that's fine (in that case all your colors must be pre-inserted into the database, or they will be inserted without Locale).
Please, keep in mind, that setting Locale.GERMAN has no effect on a database in this case. It will be silently ignored and if you don't have such a color in a database, it will be inserted with null.
Color assigned to only one box
If you model this relationship, you make a single Color (like Black in German) be assigned to only one Box. It sounds a bit unnatural. Usually, I would assume Black can be assigned to many Boxes. So, it would be a ManyToMany
relationship. Again, if this is on purpose, that's fine!
ColorId as a primary key
It's also a bit unnatural to have Locale
as a part of a primary key in Color
-- Black in German and Black in English as different colors? The colors themselves are locale-independent. The name of a color is locale-dependent, but it's more a matter of UI. Again, if this is on purpose, that's fine! After all, it's your business model!