Spring Data JPA通过嵌入式对象属性查找


101

我想编写一个Spring Data JPA存储库接口方法签名,该签名可以让我在该实体中找到具有嵌入式对象属性的实体。有人知道这是否可行吗?

这是我的代码:

@Entity
@Table(name = "BOOK_UPDATE_QUEUE", indexes = { uniqueConstraints = @UniqueConstraint(columnNames = {
        "bookId", "region" }, name = "UK01_BOOK_UPDATE_QUEUE"))
public class QueuedBook implements Serializable {

    @Embedded
    @NotNull
    private BookId bookId;

    ...

}

@Embeddable
public class BookId implements Serializable {

    @NotNull
    @Size(min=1, max=40)
    private String bookId;

    @NotNull
    @Enumerated(EnumType.STRING)
    private Region region;

    ...

}

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

    //I'd like to write a method like this, but can't figure out how to search by region,
    //when region is actually a part of the embedded BookId
    Page<QueuedBook> findByRegion(Region region, Pageable pageable);

}

我可以使用Spring Data为此编写查询吗?


4
没办法findByBookIdRegion(Region region, Pageable pageable)吗?
奥利弗·德罗博姆

2
是的,做到了。我找不到任何地方的文档。它是隐藏还是隐含在我没看见的地方?
CorayThan

将其转化为答案,并添加了指向参考文档相关部分的链接。
奥利弗·德罗博姆

Answers:


145

此方法名称应能解决问题:

Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);

有关参考文档的查询派生的部分中的更多信息。


11
如果我有嵌入式清单,该怎么办?或元素集合?
user962206 '16

如果我们想查询具有3个属性的findBy,那么语法是什么?像findByPro1AndPro2AndPro3吗?
surendrapanday

这样的查询是否总是导致内部联接?我正在执行One findByIdAndTwoId(Long oneId, Long twoId);并导致以下形式的查询:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
TroJaN


9

如果将BookId用作组合主键,请记住将界面从以下位置更改:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long> {

至:

public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId> {

并在QueuedBook类中将注释@Embedded更改为@EmbeddedId,如下所示:

public class QueuedBook implements Serializable {

@EmbeddedId
@NotNull
private BookId bookId;

...

1

根据我的说法,Spring无法轻松处理所有情况。在您的情况下,以下方法可以解决问题

Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);  

要么

Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);

但是,这也取决于您在@Embeddable班级中使用的字段的命名约定,

例如,以下字段可能不适用于上述任何样式

private String cRcdDel;

我尝试了两种情况(如下),但没有用(似乎Spring无法处理这种类型的命名约定(例如,对于许多Caps,尤其是开头的第二个字母)(不确定这是否是唯一的情况)

Page<QueuedBook> findByBookIdCRcdDel(String cRcdDel, Pageable pageable); 

要么

Page<QueuedBook> findByBookIdCRcdDel(String cRcdDel, Pageable pageable);

当我重命名列为

private String rcdDel;

我的以下解决方案工作正常,没有任何问题:

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable); 

要么

Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.