Selon documentation Hibernate , plusieurs annotations sont disponibles si nous voulons utiliser Map comme association entre nos entités. Le doc dit:
Alternativement, la clé de mappage est mappée sur une ou plusieurs colonnes dédiées. Afin de personnaliser le mappage, utilisez l'une des annotations suivantes:
@MapKeyColumn si la clé de carte est un type de base. Si vous ne spécifiez pas le nom de la colonne, le nom de la propriété suivi du trait de soulignement suivi de KEY est utilisé (par exemple Orders_KEY). @MapKeyEnumerated/@MapKeyTemporal si le type de clé de carte est respectivement une énumération ou une date. @ MapKeyJoinColumn/@ MapKeyJoinColumns si le type de clé de carte est une autre entité. @ AttributeOverride/@ AttributeOverrides lorsque la clé de carte est un objet intégrable. Utilisez la clé. comme préfixe pour vos noms de propriétés d'objet intégrables. Vous pouvez également utiliser @MapKeyClass pour définir le type de la clé si vous n'utilisez pas de génériques.
En faisant quelques exemples, je peux comprendre que @MapKey est juste utilisé pour mapper la clé à une propriété de l'entité cible et cette clé est utilisée uniquement pour récupérer des enregistrements. @MapKeyColumn est utilisé pour mapper la clé sur une propriété de l'entité cible et cette clé est utilisée pour enregistrer ainsi que pour récupérer des enregistrements. Veuillez me faire savoir si c'est correct?
Veuillez également me faire savoir quand j'ai besoin d'utiliser @ MapKeyJoinColumn/@ MapKeyJoinColumns & @MapKeyEnumerated/@MapKeyTemporal
Merci!
Lorsque vous utilisez un Map
, vous devez toujours associer au moins deux entités. Disons que nous avons une entité Owner
qui se rapporte à l'entité Car
(Car
a un FK à Owner
).
Ainsi, le Owner
aura un Map
de Car(s)
:
Map<X, Car>
@MapKey
Le @MapKey
vous donnera le Car's
propriété utilisée pour regrouper un Car
dans son Owner
. Par exemple, si nous avons une propriété vin
(numéro d'identification du véhicule) dans Car
, nous pourrions l'utiliser comme clé carMap
:
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKey(name = "vin")
private Map<String, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
private String vin;
}
@MapKeyEnumerated
Le @MapKeyEnumerated
utilisera un Enum de Car
, comme WheelDrive
:
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKeyEnumerated(EnumType.STRING)
private Map<WheelDrive, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
@Column(name = "wheelDrive")
@Enumerated(EnumType.STRING)
private WheelDrive wheelDrive;
}
public enum WheelDrive {
2WD,
4WD;
}
Cela regroupera les voitures par leur type de WheelDrive.
@MapKeyTemporal
Le @MapKeyTemporal
utilisera un champ Date
/Calendar
pour le regroupement, comme createdOn
.
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKeyTemporal(TemporalType.TIMESTAMP)
private Map<Date, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="created_on")
private Calendar createdOn;
}
@MapKeyJoinColumn
Le @MapKeyJoinColumn
nécessite une troisième entité, comme Manufacturer
pour que vous ayez une association de Owner
à Car
et car a également une association à un Manufacturer
, donc que vous pouvez regrouper tous Owner's
Cars
par Manufacturer
:
@Entity
public class Owner {
@Id
private long id;
@OneToMany(mappedBy="owner")
@MapKeyJoinColumn(name="manufacturer_id")
private Map<Manufacturer, Car> carMap;
}
@Entity
public class Car {
@Id
private long id;
@ManyToOne
private Owner owner;
@ManyToOne
@JoinColumn(name = "manufacturer_id")
private Manufacturer manufacturer;
}
@Entity
public class Manufacturer {
@Id
private long id;
private String name;
}
Voici un exemple pratique d'utilisation de @MapKey avec @OneToMany avec une @IdClass composite. Ce n'est évidemment pas la seule façon d'atteindre l'objectif ici, mais j'ai senti que c'était la plus maintenable.
@Entity
@Table(name = "template_categories")
@IdClass(TemplateCategoryId.class)
public class TemplateCategory implements Serializable {
private static final long serialVersionUID = 1L;
@Id
long orgId;
@Id
long templateId;
@OneToMany(targetEntity = TemplateEntry.class)
@JoinColumns( {
@JoinColumn(name = "orgId", referencedColumnName = "orgId"),
@JoinColumn(name = "templateId", referencedColumnName = "templateId")
}
)
@MapKey(name="key")
private Map<String, TemplateEntry> keyMap;