java - Diferencia entre @MapKey, @MapKeyColumn y @MapKeyJoinColumn en JPA e Hibernate
orm hibernate-mapping (1)
Cuando utiliza un Map
, siempre debe asociar al menos dos entidades. Digamos que tenemos una entidad de Owner
que se relaciona con la entidad de Car
(el Car
tiene un FK a Owner
).
Por lo tanto, el Owner
tendrá un Map
de Car(s)
:
Map<X, Car>
@MapKey
La @MapKey
le dará la propiedad Car''s
utilizada para agrupar un Car
a su Owner
. Por ejemplo, si tenemos una propiedad vin
(Número de identificación del vehículo) en Car
, podríamos usarla como clave de 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
La @MapKeyEnumerated
usará un Enum from Car
, como 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;
}
Esto agrupará los coches por su tipo WheelDrive.
@MapKeyTemporal
La @MapKeyTemporal
utilizará un campo Date
/ Calendar
para agrupar, como 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
La @MapKeyJoinColumn
requiere una tercera entidad, como el Manufacturer
para que tenga una asociación de Owner
a Car
y el coche también tiene una asociación con un Manufacturer
, para que pueda agrupar todos Owner''s
Cars
Owner''s
por 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;
}
Según la documentación de Hibernate , hay múltiples anotaciones disponibles si queremos usar Map como una asociación entre nuestras entidades. El doc dice:
Alternativamente, la clave del mapa se asigna a una columna o columnas dedicadas. Para personalizar el mapeo use una de las siguientes anotaciones:
@MapKeyColumn si la clave del mapa es un tipo básico. Si no especifica el nombre de la columna, se usa el nombre de la propiedad seguido de un guión bajo seguido de la CLAVE (por ejemplo, orders_KEY). @MapKeyEnumerated / @MapKeyTemporal si el tipo de clave del mapa es respectivamente una enumeración o una Fecha. @ MapKeyJoinColumn / @ MapKeyJoinColumns si el tipo de clave de mapa es otra entidad. @ AttributeOverride / @ AttributeOverrides cuando la clave del mapa es un objeto que se puede insertar. Utilice la clave. como un prefijo para sus nombres de propiedad de objeto integrables. También puede usar @MapKeyClass para definir el tipo de clave si no usa los genéricos.
Al hacer algunos ejemplos, puedo entender que @MapKey solo se usa para asignar la clave a una propiedad de la entidad objetivo y esta clave se usa solo para obtener registros. @MapKeyColumn se usa para asignar la clave a una propiedad de la entidad objetivo y esta clave se usa para guardar y recuperar registros. Por favor, hágamelo saber si esto es correcto?
Además, avíseme cuando necesite usar @ MapKeyJoinColumn / @ MapKeyJoinColumns & @MapKeyEnumerated / @MapKeyTemporal
¡Gracias!