Hibernate搜索:在复合键EmbeddedId中搜索
我将classHibernate搜索:在复合键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 = {
CKey
定义为嵌入式id类
我定义了classBEntity
,并使用双向字符串字段桥接器作为复合主键
我将类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,但当我重新启动应用程序时,它返回数据。我认为问题在于索引的构建。我加了这一行。我添加了这个lignefullTextEntityManager.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);