I want to have an entity
class InkFormula {
int id;
Map<Ink, Integer> inkPercents;
...
}
from a single table with such a structure:
┌─────┬────────┬─────────┐
│ id │ ink_id │ percent │
├─────┼────────┼─────────┤
│ 1 │ 1 │ 50 │
├─────┼────────┼─────────┤
│ 1 │ 2 │ 25 │
├─────┼────────┼─────────┤
│ 1 │ 3 │ 0 │
├─────┼────────┼─────────┤
│ 2 │ 1 │ 100 │
├─────┼────────┼─────────┤
│ 2 │ 2 │ 80 │
└─────┴────────┴─────────┘
where non-unique id
must be used to congregate a Map<>
from ink_id
and percent
.
The reason why I need a single entity and a single table is a requirement to have unique constraint id
, ink_id
so that each formula could not contain repeated inks.
Is that possible with JPA and Hibernate?
I would create a composite primary key InkFormulaId
which contains two fields: id
and ink_id
similar to
@Embeddable
public class InkFormulaId implements Serializable {
private Integer id;
private Integer inkId;
// ...
}
@Entity
public class InkFormula {
@EmbeddedId
private InkFormulaId inkFormulaId;
@ManyToOne
@MapsId(value = "inkId")
private Ink ink;
private Integer percents;
// ...
}
so each InkFormula
represents a single line in your table above with a unique primary key ( id
, inkId
) and their percents
.
To get the mapping you mentioned above, you would have to SELECT
all InkFormula
for a single id
and then group them by inkId
in your Java code.
An alternative solution could be using an @ElementCollection
annotation and separating data into two tables:
ink_formula ink_formula_ink_percent
┌───┐ ┌──────────────┬──────┬───────┐
│id │ │ink_formula_id│ink_id│percent│
├───┤ ├──────────────┼──────┼───────┤
│ 1 │ │ 1 │ 1 │ 20 │
├───┤ ├──────────────┼──────┼───────┤
│ 2 │ │ 1 │ 2 │ 55 │
├───┤ ├──────────────┼──────┼───────┤
. . . . . . . . . . . . . . . . . . .
The entity class will then look like
@Entity
public class InkFormula {
@Id
@GeneratedValue
int id;
@ElementCollection
@CollectionTable(
name="ink_formula_ink_percent",
joinColumns=@JoinColumn(name="ink_formula_id")
)
@MapKeyJoinColumn(name="ink_id")
@Column(name = "percent")
private Map<Ink, Integer> inkPercents = new TreeMap<>();
//...
}
This setup satisfies the unique InkFormula-Ink
requirement but we need a separate table for InkFormula
.
Next question is how to ensure the uniqueness of each InkFormula
since two InkFormulas
with different id
s can hold the same values in their inkPercents
maps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.