Почему JPQL игнорирует родительские поля?

#jpa #jpql

#jpa #jpql

Вопрос:

Стек приложения: Hibernate , Spring Data , JPA .

В приложении есть несколько объектов. Я пытаюсь сделать JPQL-запрос в репозитории моего класса OpenParagraph .

OpenParagraph:

 @Entity
@Table(name = "open_paragraphs")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class OpenParagraph extends ProgramEntry {

    @NotNull
    @Column(name = "sort_num")
    private Integer sortNum;
}
 

OpenParagraph имеет родительский: абстрактный класс ProgramEntry .

ProgramEntry:

 @MappedSuperclass
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public abstract class ProgramEntry extends AbstractBaseEntity {

    @NotNull
    @ManyToOne
    @JoinColumn(name = "paragraph_id")
    private Paragraph paragraph;

    @NotNull
    @ManyToOne
    @JoinColumn(name = "program_id")
    private Program program;
}
 

Итак, я пытаюсь обратиться к OpenParagraph полю «Абзац», но IDEA подсказывает мне, что это ошибка:

введите описание изображения здесь

Он не предлагает мне поле «программа»:

введите описание изображения здесь

IDEA предлагает поля только из OpenParagraph , а не из родительского.

Мой вопрос: это ошибка IDEA? Если это не ошибка IDEA, то как я могу вызвать «program» в этом запросе?

Комментарии:

1. Вы пытались выполнить код? Каков был результат?

2. @Lefteris нет. Я все еще создаю сервисы, я не могу запустить приложение и не могу проверить

Ответ №1:

Это ошибка Intellij IDEA (возможно, связанная с этим?). Но:

Можно выполнять запросы по полям суперкласса (или MappedSuperclass ). Вот пример:

 @MappedSuperclass
@Getter
@Setter
public class Foo extends AbstractPersistable<Long> {

    @Column
    private String fooValue;
    
}

@Entity
@Getter
@Setter
public class Bar extends Foo {

    @Column
    private String barValue;
    
}

public interface BarRepository extends JpaRepository<Bar, Long> {

    @Query("SELECT b FROM Bar b WHERE b.fooValue = ?1")
    List<Bar> findByFooValue(String fooValue);
    
}
 

Учитывая это, при вызове метода репозитория будет зарегистрировано что-то вроде этого (с включенным ведением журнала sql):

 Hibernate: select bar0_.id as id1_0_, bar0_.foo_value as foo_valu2_0_, bar0_.bar_value as bar_valu3_0_ from bar bar0_ where bar0_.foo_value=?
 

Подсказка:

Если вы используете Spring Boot (с тестовой зависимостью / зависимостями и встроенной тестовой базой данных, такой как h2), довольно легко выполнить такие методы без запуска всего приложения. Здесь просто небольшой фрагмент, который выполнит метод (хотя это и не тест, но этого достаточно, чтобы как-то вызывать методы):

 @SpringBootTest
public class BarRepositoryTest {

    @Autowired
    BarRepository barRepository;
    
    @Test
    public void testFindByFooValue() {
        barRepository.findByFooValue("foo");
    }
    
}