首页 > 解决方案 > Hibernate 搜索:在复合键 EmbeddedId 中搜索

问题描述

我将类CKey定义为嵌入式 id 类。

我定义了类BEntity并为复合主键使用了双向字符串字段桥。

AEntity用与 的关系ManyToOne来定义类BEntity

@Entity @Indexed
public class AEntity {
    @ManyToOne(optional = false) @IndexedEmbedded(depth = 1, includeEmbeddedObjectId = true)
    @JoinColumns(value = { @JoinColumn(name = "fk_fId", referencedColumnName = "fId"),
            @JoinColumn(name = "fk_sId", referencedColumnName = "sId") }, foreignKey = @ForeignKey(name = "fk_sub"))
    private BEntity bEntity;
}

@Entity @Indexed
public class BEntity {
    @EmbeddedId @IndexedEmbedded @FieldBridge(impl = CompositeIdBridge.class)
    private CKey cKey;
}


@Embeddable @Indexed
public class CKey {
    @Field
    private String fId;
    @Field
    private String sId;
}

public class CompositeIdBridge implements TwoWayStringBridge {
    @Override
    public String objectToString(Object object) {
       return String.format("%s.%s", (CKey) object.getFId(), (CKey) object.getSId());
    }
    @Override
    public Object stringToObject(String stringValue) {
       String[] compositeIdProperties = stringValue.split("\\.");
       return new CKey(compositeIdProperties[1], compositeIdProperties[2]);
    }
}

然后,我尝试对 Entity 类进行休眠搜索AEntity,但遇到了这个异常:

无法在 AEntity 中找到字段 bEntity.cKey.fId

Query query = getQuery().bool()
                .must(getQuery().keyword().onField("bEntity.cKey.fId").matching("111111").createQuery())
                .must(getQuery().keyword().onField("bEntity.cKey.sId").matching("222222").createQuery()).createQuery();
FullTextQuery fullTextQuery = getFullTextEntityManager().createFullTextQuery(query, AEntity.class);

标签: hibernatelucenehibernate-search

解决方案


@IndexedEmbedded(depth = 1)的 inAEntity明确要求仅嵌入深度为 1 的字段。bEntity.cKey相对于 位于深度 1 bEntity,但bEntity.cKey.fIdbEntity.cKey.sId位于深度 2。

要么你应该增加深度:

@Entity @Indexed
public class AEntity {
    @ManyToOne(optional = false)
    @IndexedEmbedded(depth = 2, includeEmbeddedObjectId = true)
    @JoinColumns(value = { @JoinColumn(name = "fk_fId", referencedColumnName = "fId"),
            @JoinColumn(name = "fk_sId", referencedColumnName = "sId") }, foreignKey = @ForeignKey(name = "fk_sub"))
    private BEntity bEntity;
}

...或者您应该明确包括这些字段:

@Entity @Indexed
public class AEntity {
    @ManyToOne(optional = false)
    @IndexedEmbedded(depth = 1, includeEmbeddedObjectId = true,
            includePaths = {"cKey.fId", "cKey.sId"})
    @JoinColumns(value = { @JoinColumn(name = "fk_fId", referencedColumnName = "fId"),
            @JoinColumn(name = "fk_sId", referencedColumnName = "sId") }, foreignKey = @ForeignKey(name = "fk_sub"))
    private BEntity bEntity;
}

推荐阅读