[JAVA] Existiert mit der Spezifikation in Spring Data JPA

Angenommen, Sie haben eine Tabelle mit dieser Struktur.

ER.png

Wenn Sie mit Spring Data JPA eine etwas komplizierte Abfrage ausführen möchten, verwenden Sie Specification. Wenn Sie jedoch vorhanden verwenden, hat die folgende Entitätsstruktur ein Problem verursacht. (Setter / Getter weggelassen) Die Version von Spring Boot ist übrigens 1.5.4.RELEASE.

User.java



@Entity
public class User {
    @Id
    private String userId;

    private String name;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Phone> services;
}

Phone.java


@Entity
public class Phone {
    @Id
    private Integer phoneId;

    @ManyToOne
    @JoinColumn(name = "USER_ID")
    private User user;

    private Integer type;

    private String number;
}

Bei Verwendung dieser Entität gibt es die Klausel "Für einen Benutzer mit mindestens einem Telefon".

public interface UserRepository extends CrudRepository<User, Integer>, JpaSpecificationExecutor<User> {

    static Specification<User> existsPhone() {
        return (root, query, cb) -> {
            Subquery<Integer> subquery = query.subquery(Integer.class);
            Root<Phone> subRoot = subquery.from(Phone.class);
            return cb.exists(subquery.select(cb.literal(1)).where(
                    cb.equal(root, subRoot.get("user").get("userId")));
        };
    }

}

Machen Sie wie

userRepository.findAll(Specifications.where(UserRepository.existsPhone()));

Bei der Ausführung ist ein StackOverflowError aufgetreten.

Anscheinend wurde es zirkulär als Benutzer → Telefon → Benutzer → Telefon → .... bezeichnet. ..

Wenn ich also die Benutzerreferenz wie folgt vom Telefon entferne, ist der Fehler verschwunden.

User.java



@Entity
public class User {
    @Id
    private String userId;

    private String name;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "userId")
    private List<Phone> services;
}

Phone.java


@Entity
public class Phone {
    @Id
    private Integer phoneId;

    private String userId;

    private Integer type;

    private String number;
}
public interface UserRepository extends CrudRepository<User, Integer>, JpaSpecificationExecutor<User> {

    static Specification<User> existsPhone() {
        return (root, query, cb) -> {
            Subquery<Integer> subquery = query.subquery(Integer.class);
            Root<Phone> subRoot = subquery.from(Phone.class);
            return cb.exists(subquery.select(cb.literal(1)).where(
                    cb.equal(root, subRoot.get("userId")));
        };
    }

}

Ich beziehe mich nicht einmal auf den Benutzer vom Telefon. Ist das in Ordnung?

Recommended Posts

Existiert mit der Spezifikation in Spring Data JPA
ODER suchen Sie mit der Spring Data Jpa-Spezifikation
[spring] Verwenden wir Spring Data JPA
Machen Sie die where-Klauselvariable in Spring Data JPA
[So installieren Sie Spring Data Jpa]
Spring Data JPA SQL-Protokollausgabe
Spring Data JPA: Schreiben Sie eine Abfrage in Pure SQL in @Query of Repository
[Java] Abrufen von Daten aus der Datenbank mithilfe des Singleton-Dienstes in Spring (Boot)
Null-Support-Cache in Spring Data Redis
Antwortdaten direkt im Frühjahr schreiben
Spring Data JPA Save Select-Insert ist nur Insert
Datenverwaltung mit Volume in Docker (persönliches Memorandum)
Gegenseitige Bezugnahme auf Entity of Spring Data JPA und seine Anmerkungen
Jackson kann hibernateLazyInitializer in Spring Data nicht JSON serialisieren JPA führt zu einem Fehler
Beispielcode für die DB-Steuerung durch deklarative Transaktion mit Spring Boot + Spring Data JPA
Beispielcode für die Suche mit QBE (Query by Example) von Spring Data JPA
Sortieren nach Spring Data JPA (mit zusammengesetzter Schlüsselsortierung)
Erstellen eines gemeinsamen Repositorys mit Spring Data JPA
So definieren Sie mehrere orm.xml in Spring4, JPA2.1
Spring Boot + Spring Data JPA Informationen zu mehreren Tabellenverknüpfungen
Überprüfen Sie das Verhalten von getOne-, findById- und Abfragemethoden mit Spring Boot + Spring Data JPA
Ein Memorandum beim Versuch von Spring Data JPA mit STS
Ich habe versucht, mit Spring Data JPA zu beginnen
Bis zur Verwendung von Spring Data und JPA Part 2
Testen Sie die Klasse mit Feldinjektion im Spring-Boot-Test, ohne den Spring-Container zu verwenden
Bis zur Verwendung von Spring Data und JPA Part 1
Injizieren Sie den Logger im Frühjahr
Verwenden Sie Interceptor im Frühjahr
Spring Data JDBC-Vorschau
Microservices in Spring Cloud
Holen Sie sich Cookies im Frühling
Federdaten Dynamodb-Falle
Versuchen Sie es mit Spring JDBC
Ich habe das Spring Boot-Einführungshandbuch [Zugriff auf Daten mit JPA] ausprobiert.
Authentifizieren Sie 3 oder mehr Parameter im JSON-Format mit Spring Security
Erstellen Sie eine API zum Senden und Empfangen von Json-Daten mit Spring
Abrufen von Fehlerinformationen mithilfe von DefaultErrorAttributes und ErrorAttributeOptions in Spring Boot 2.3
8 Dinge, die mit Spring Boot und JPA in die DB eingefügt werden müssen
So steuern Sie Transaktionen in Spring Boot ohne Verwendung von @Transactional
[Spring Data JPA] Die benutzerdefinierte ID wird zum Zeitpunkt der Registrierung in einer eindeutigen Reihenfolge zugewiesen.