Hibernate 搜索:在复合键 EmbeddedId 中搜索
Hibernate search: search in composite key EmbeddedId
我将 class CKey
定义为嵌入式 ID class。
我定义了 class BEntity
并为复合主键使用了双向字符串字段桥。
我用 ManyToOne
和 BEntity
定义了 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.fId
和 bEntity.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;
}
我将 class CKey
定义为嵌入式 ID class。
我定义了 class BEntity
并为复合主键使用了双向字符串字段桥。
我用 ManyToOne
和 BEntity
定义了 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.fId
和 bEntity.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;
}