Spring Data Repository: что такое управляемый тип? - PullRequest
0 голосов
/ 09 января 2020

По моему мнению, JavaDo c для org.springframework.data.repository.Repository является неточным для параметра c generic <T>. Он говорит:

@ param тип домена, которым управляет репозиторий

Хорошо.

Предположим, у нас есть следующие объекты:

@Entity
@Table
public class Parent {
    @Id
    private Long id;

    @Getter
    @OrderBy
    @OneToMany(mappedBy = "parent")
    private Set<Children> children;
}

@Entity
@Table
public class Children {
    @Id
    private Long id;

    @OneToOne
    @JoinColumn(name = "parent_id", nullable = false)
    private Parent parent;
}

Если все дочерние элементы для родителя запрашиваются, какой репозиторий является правильным?

public interface ParentRepository extends Repository<Parent, Long> {
    // IntelliJ Warning: 'Children' domain type or valid projection interface expected here
    @Query("SELECT children FROM Parent WHERE id = ?1")
    List<Children> getChildrenByParentId(Long parentId);
}

public interface ChildrenRepository extends Repository<Children, Long> {
    @Query("SELECT children FROM Parent WHERE id = ?1")
    List<Children> getChildrenByParentId(Long parentId);
}

Как насчет этого дополнительного запроса?

@Query("SELECT parent.children FROM Parent parent LEFT JOIN parent.children children WHERE parent.id = ?1 ORDER BY children.id")
List<Children> getOrderedChildrenByParentId(Long parentId);

Поскольку он работает независимо от того, какой репозиторий является использовал мой интерес больше, почему ParentRepository или ChildrenRepository является правильным.

После просмотра документации: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#reference ParentRepository кажется более правильным - хотя IntelliJ предупреждение.

1 Ответ

1 голос
/ 09 января 2020

Если вы создаете интерфейс:

public interface ParentRepository extends Repository<Parent, Long>

Параметр Parent используется для генерации таких методов, как findAll findOne et c. чтобы вернуть правильный тип, а параметр Long используется в качестве типа первичного ключа.

Если вы сделаете:

@Query("SELECT parent.children FROM Parent parent LEFT JOIN parent.children children WHERE parent.id = ?1 ORDER BY children.id")
List<Children> getOrderedChildrenByParentId(Long parentId);

Вы абсолютно свободны, какие типы параметров и какой тип возврата вы хотите использовать. Поэтому не имеет значения, куда вы помещаете метод с аннотацией @Query.

...