Hibernate 搜索:在复合键 EmbeddedId 中搜索

Hibernate search: search in composite key EmbeddedId

我将 class CKey 定义为嵌入式 ID class。

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

我用 ManyToOneBEntity 定义了 class AEntity

@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]);
    }
}

然后,我尝试对实体 class AEntity 进行休眠搜索,但 运行 进入此异常:

Unable to find field bEntity.cKey.fId in AEntity

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);

您在 AEntity 中的 @IndexedEmbedded(depth = 1) 明确要求仅嵌入深度为 1 的字段。 bEntity.cKey 相对于 bEntity 处于深度 1,但 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;
}