Репозиторий данных Spring: что такое управляемый тип?

По моему мнению, JavaDoc для org.springframework.data.repository.Repository является неточным в отношении общего параметра <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.


person Sven Döring    schedule 09.01.2020    source источник
comment
Ответ Саймонса ниже подводит итог правильно. Вероятно, что-то, что следует обсудить с командой IntelliJ.   -  person Oliver Drotbohm    schedule 10.01.2020


Ответы (1)


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

public interface ParentRepository extends Repository<Parent, Long>

Параметр Parent используется для создания таких методов, как findAll findOne и т. Д., Для возврата правильного типа, а параметр 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.

person Simon Martinelli    schedule 09.01.2020