问题描述
应用的堆栈:Hibernate
、Spring Data
、JPA
。
应用中有一些实体。我尝试在我的类 OpenParagraph
的存储库中进行 JPQL 查询。
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
。
程序入口:
@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 的失败,那么我如何在此查询中调用“程序”?
解决方法
这是/曾经是 Intellij IDEA 的一个错误(可能与 this 相关?)。但是:
可以通过超类(或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");
}
}