Le mappage avec la table d'intersection est toujours ennuyeux. Cette fois, je présenterai la méthode d'enregistrement lorsque vous avez une clé non composite dans la table d'intersection.
Tout d'abord, supposons que vous ayez une entité avec les relations suivantes:
La méthode de sauvegarde dans ce cas est la suivante.
Maître des utilisateurs
@Getter
@NoArgsConstructor
@EqualsAndHashCode(of = {"id"})
@Entity
@Table
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String status;
@ManyToMany
@JoinTable(name = "user_service",joinColumns = @JoinColumn(name="user_id"), referencedColumnName="id"
inverseJoinColumns = @JoinColumn(name="service_id", referencedColumnName="id"))
private List<Service> services = new ArrayList<>();
public User(String name,String status){
this.name = name;
this.status = status;
}
//Ajouter des services à utiliser
public void addService(Service service){
services.add(service);
}
}
Maître de service
@Getter
@NoArgsConstructor
@EqualsAndHashCode(of = {"id"})
@Entity
@Table
public class Service implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String status;
public Service(String name,String status) {
this.name = name;
this.status = status;
}
}
processus d'inscription
User user = entityManager.find(User.class,<Identifiant d'utilisateur>);
Service service = entityManager.find(Service.class,<ID de service à utiliser>);
user.addService(service);
entityManager.persist(user);
Ajoutez «Date de début» au tableau des services d'utilisation.
Dans ce cas, la date de début d'utilisation ne peut pas être enregistrée uniquement avec `` @ JoinTable '', donc une classe d'entité sera créée en tant que service d'utilisation.
Service utilisé
@Getter
@NoArgsConstructor
@EqualsAndHashCode(of = {"id"})
@Entity
@Table(name = "user_service")
public class UserService implements Serializable {
@EmbeddedId
private PrimaryKey pk;
@Column(name = "begin_date")
private LocalDate beginDate;
@ManyToOne
@MapsId("userId")
private User user;
@ManyToOne
@MapsId("serviceId")
private Service service;
public UserService(User user, Service service,LocalDate beginDate) {
this.user = user;
this.service = service;
this.beginDate = beginDate;
}
@Getter
@NoArgsConstructor
@Embeddable
public static class PrimaryKey implements Serializable {
@Column(name = "user_id")
private Long userId;
@Column(name = "service_id")
private Long serviceId;
}
}
L'important ici est `` @ MapsId ''. Spécifiez le nom de champ défini dans la classe PrimaryKey que vous souhaitez mapper à l'argument. Cela associe la classe d'entité à la clé composite.
Modifiez également le maître utilisateur. À l'origine, j'ai pu obtenir le service que j'utilise auprès du maître des utilisateurs. Obtenez-le via votre classe de service.
Maître des utilisateurs
@Getter
@NoArgsConstructor
@EqualsAndHashCode(of = {"id"})
@Entity
@Table
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String status;
@OneToMany(mappedBy = "user")
private List<UserService> services = new ArrayList<>();
public User(String name,String status){
this.name = name;
this.status = status;
}
//Ajouter des services à utiliser
public void addService(Service service){
services.add(new UserService(this, service, LocalDate.now()));
}
//Je retournerai une liste de services au lieu d'une liste de tables d'intersection
public List<Service> getServices(){
return services.stream().map(UserService::getService).collect(Collectors.toList());
}
}
Exemple de processus d'inscription
User user = entityManager.find(User.class,<Identifiant d'utilisateur>);
Service service = entityManager.find(Service.class,<ID de service à utiliser>);
user.addServices(service);
entityManager.persist(user);
Recommended Posts