[JAVA] [JPA] Speichern, wenn Sie andere Elemente als Schlüssel in der Schnittpunkttabelle haben, die sich auf ManyToMany beziehen

Einführung

Das Mappen mit der Kreuzungstabelle ist immer ärgerlich. Dieses Mal werde ich die Registrierungsmethode einführen, wenn Sie einen nicht zusammengesetzten Schlüssel in der Schnittpunkttabelle haben.

Nur Registrierung des zusammengesetzten Schlüssels

Angenommen, Sie haben eine Entität mit den folgenden Beziehungen:

1.png

Die Speichermethode ist in diesem Fall wie folgt.

Benutzerstamm


@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;
    }

    //Fügen Sie zu verwendende Dienste hinzu
    public void addService(Service service){
        services.add(service);
    }
}

Service Master


@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;
    }
}

Registrierungsprozess


User user = entityManager.find(User.class,<Benutzeridentifikation>);
Service service = entityManager.find(Service.class,<Zu verwendende Service-ID>);
user.addService(service);
entityManager.persist(user);

Registrierung, wenn ein anderes Element als der zusammengesetzte Schlüssel vorhanden ist

Fügen Sie der Nutzungsdiensttabelle "Startdatum" hinzu.

1.png

In diesem Fall kann das Startdatum der Nutzung nicht nur mit "@ JoinTable" gespeichert werden, sodass eine Entitätsklasse als Nutzungsdienst erstellt wird.

Service verwendet


@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;
    }
}

Das Wichtigste hier ist "@ MapsId". Geben Sie den in der PrimaryKey-Klasse definierten Feldnamen an, den Sie dem Argument zuordnen möchten. Dadurch wird die Entitätsklasse dem zusammengesetzten Schlüssel zugeordnet.

Ändern Sie auch den Benutzerstamm. Ursprünglich konnte ich den von mir verwendeten Dienst vom Benutzerstamm erhalten. Erhalten Sie es über Ihre Serviceklasse.

Benutzerstamm


@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;
    }
    
    //Fügen Sie zu verwendende Dienste hinzu
    public void addService(Service service){
        services.add(new UserService(this, service, LocalDate.now()));
    }

    //Ich werde eine Liste von Diensten anstelle einer Liste von Schnittpunkttabellen zurückgeben
    public List<Service> getServices(){
        return services.stream().map(UserService::getService).collect(Collectors.toList());
    }
}

Beispiel für den Registrierungsprozess


User user = entityManager.find(User.class,<Benutzeridentifikation>);
Service service = entityManager.find(Service.class,<Zu verwendende Service-ID>);
user.addServices(service);
entityManager.persist(user);

Recommended Posts

[JPA] Speichern, wenn Sie andere Elemente als Schlüssel in der Schnittpunkttabelle haben, die sich auf ManyToMany beziehen
So geben Sie den Wert aus, wenn sich ein Array im Array befindet
[Schienen] So registrieren Sie mehrere Datensätze in der Zwischentabelle mit einer Zuordnung von vielen zu vielen
So ändern Sie den Prozess in Abhängigkeit von der Liste, die gedrückt wird, wenn mehrere ListViews vorhanden sind
So stellen Sie die Chronik ein, wenn sich die Zeit in CentOS7 verschiebt
Was tun, wenn die Änderungen im Servlet nicht berücksichtigt werden?
[jOOQ] Wie in der WHERE / AND / OR-Klausel WANN FALLEN
(Spring-data-jpa) So erhalten Sie POJO (außer Entitätsklasse) mit JPA2.1
So beheben Sie den unbekannten Fehler, der bei der Verwendung von slf4j in Java aufgetreten ist
Warum hört es auf, wenn ich in Eclipse debugge und es keine Haltepunkte gibt? Links zu
So ermitteln Sie die Gesamtzahl der Seiten beim Paging in Java
So beschränken Sie die Aktion des Übergangsziels, wenn Sie nicht angemeldet sind
So verweisen Sie auf eine Spalte, wenn Sie die Spaltennamensmethode in ActiveRecord überschreiben