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

Hibernate搜索:在复合键EmbeddedId中搜索,hibernate,lucene,hibernate-search,Hibernate,Lucene,Hibernate Search,我将classCKey定义为嵌入式id类 我定义了classBEntity,并使用双向字符串字段桥接器作为复合主键 我将类AEntity与manytone的关系定义为BEntity @Entity @Indexed public class AEntity { @ManyToOne(optional = false) @IndexedEmbedded(depth = 1, includeEmbeddedObjectId = true) @JoinColumns(value = {

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

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

我将类
AEntity
manytone
的关系定义为
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]);
    }
}
然后,我尝试在实体类
AEntity
上执行hibernate搜索,但遇到以下异常:

在AEntity中找不到字段bEntity.cKey.fId


AEntity
中的
@IndexedEmbedded(depth=1)
明确要求仅嵌入深度为1的字段<相对于
bEntity
,code>bEntity.cKey位于深度1,但是
bEntity.cKey.fId
bEntity.cKey.sId
位于深度2

或者,您应该增加深度:

@Entity@index
公共类实体{
@多通(可选=假)
@IndexedEmbedded(深度=2,includeEmbeddedObjectId=true)
@JoinColumns(值={@JoinColumn(name=“fk_fId”,referencedColumnName=“fId”),
@JoinColumn(name=“fk_sId”,referencedColumnName=“sId”)},foreignKey=@foreignKey(name=“fk_sub”))
私人本钱;
}
。。。或者,您应该明确包括以下字段:

@Entity@index
公共类实体{
@多通(可选=假)
@IndexedEmbedded(深度=1,includeEmbeddedObjectId=true,
includePath={“cKey.fId”,“cKey.sId”})
@JoinColumns(值={@JoinColumn(name=“fk_fId”,referencedColumnName=“fId”),
@JoinColumn(name=“fk_sId”,referencedColumnName=“sId”)},foreignKey=@foreignKey(name=“fk_sub”))
私人本钱;
}

深度为2时,不再显示错误。尽管数据库中存在数据,但查询返回null。第一次启动应用程序时,它返回null,但当我重新启动应用程序时,它返回数据。我认为问题在于索引的构建。我加了这一行。我添加了这个ligne
fullTextEntityManager.createIndexer().startAndWait()它现在第一次工作,但是需要很长时间才能获得数据。还有其他解决方案吗?
fullTextEntityManager.createIndexer().startAndWait()生成索引。可以将其视为初始化数据库的SQL脚本的等价物。这不是每个查询都应该做的事情。您应该在第一次启动应用程序时只执行一次。最简单的方法通常是在管理控制台中放置一个按钮。
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);