本文介绍了如何在休眠搜索中索引复合主键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我具有以下类定义,对于类UserAdAccount,它同时使用adAccountId和userId作为其复合主键.我需要使用此复合主键作为索引的文档ID.在阅读《 Hibernate Search 5.11.5.Final:参考指南》(这是我正在使用的版本)之后,我发现了以下内容:功能更强大的TwoWayFieldBridge界面允许您将多个字段存储到索引中,这对于复合属性很有用,但实现起来较为复杂.我不确定如何继续使用TwoWayFieldBridge在这里解决我的需求.感谢您的帮助! @Entity(名称="JHI_USER_AD_ACCOUNT")@索引@IdClass(UserAdAccountId.class)@盖特@Setter公共类UserAdAccount实现SearchableEntity,可序列化{//新添加的带有双向字符串桥的id字段@DocumentId@Column(名称="ID")@FieldBridge(impl = UserAdAccoutPrimaryKeyBridge.class)私人UserAdAccountId ID;@ID@Column(名称="AD_ACCOUNT_ID")@GenericGenerator(name ="native",strategy ="native")@场地私人Long adAccountId;@ID@Column(名称="USER_ID")@GenericGenerator(name ="native",strategy ="native")@场地私有Long userId;@多多@JoinColumn(名称="USER_ID",referencedColumnName ="ID",可更新=假,可插入=假)@JsonIgnore私人用户用户;@多多@JoinColumn(名称="AD_ACCOUNT_ID",referencedColumnName ="ID",可更新=假,可插入=假)@IndexedEmbedded(includePaths ="name")私人AdAccount adAccount;}@盖特@Setter@EqualsAndHashCode(of = {"userId","adAccountId"})公共类UserAdAccountId实现Serializable {私有Long userId;私人Long adAccountId;}公共类UserAdAccoutPrimaryKeyBridge实现TwoWayStringBridge {@Overridepublic String objectToString(Object object){UserAdAccountId userAdAccountId =(UserAdAccountId)对象;StringBuilder buffer = new StringBuilder();buffer.append(userAdAccountId.getUserId()).append(-").append(userAdAccountId.getAdAccountId());返回buffer.toString();}@Override公共对象stringToObject(String value){String []组件= value.split(-");UserAdAccountId userAdAccountId = new UserAdAccountId();userAdAccountId.setUserId(Long.parseLong(components [0]));userAdAccountId.setAdAccountId(Long.parseLong(components [1]));返回userAdAccountId;}} 解决方案来自文档:您可以找到复合主键的示例实现在github上: 公共类PersonPKBridge实现TwoWayFieldBridge,MetadataProvidingFieldBridge {私有静态最终字符串FIRST_NAME_SUFFIX ="_content.firstName";私有静态最终字符串LAST_NAME_SUFFIX ="_content.lastName";@Override公共无效configureFieldMetadata(字符串名称,FieldMetadataBuilder构建器){builder.field(名称+ FIRST_NAME_SUFFIX,FieldType.STRING).field(name + LAST_NAME_SUFFIX,FieldType.STRING);}@Overridepublic Object get(字符串名称,文档文档){PersonPK id =新的PersonPK();IndexableField字段= document.getField(名称+ FIRST_NAME_SUFFIX);id.setFirstName(field.stringValue());字段= document.getField(名称+ LAST_NAME_SUFFIX);id.setLastName(field.stringValue());返回ID;}@Overridepublic String objectToString(Object object){PersonPK id =(PersonPK)对象;StringBuilder sb = new StringBuilder();sb.append(id.getFirstName()).append(").append(id.getLastName());返回sb.toString();}@Override公共无效集(字符串名称,对象值,文档文档,LuceneOptions luceneOptions){PersonPK id =(PersonPK)值;//将每个属性存储在唯一的字段中luceneOptions.addFieldToDocument(name + FIRST_NAME_SUFFIX,id.getFirstName(),document);luceneOptions.addFieldToDocument(name + LAST_NAME_SUFFIX,id.getLastName(),document);//将唯一的字符串表示形式存储在指定的字段中luceneOptions.addFieldToDocument(name,objectToString(id),document);复制代码}} 或者,如果您确定ID的组成部分不包含某个字符串,则可以将该字符串用作ID的索引形式的分隔符,并且可以进行转换索引形式返回到原始ID.这意味着您可以使用更简单的 TwoWayStringBridge 并依靠串联/拆分: 公共类PersonPKBridge实现TwoWayStringBridge {@Overridepublic String objectToString(Object object){PersonPK id =(PersonPK)对象;StringBuilder sb = new StringBuilder();sb.append(id.getFirstName()).append(").append(id.getLastName());返回sb.toString();}@Override公共对象stringToObject(String value){String []组件= value.split(");PersonPK id =新的PersonPK();id.setFirstName(components [0]);id.setLastName(components [1]);返回ID;}} I have the following class definitions and for class UserAdAccount, it uses both the adAccountId and userId as its composite primary key. I need to use this composite primary key as the document id for indexing.After reading the Hibernate Search 5.11.5.Final: Reference Guide(This is the version I am using), I found the following:The more powerful TwoWayFieldBridge interface allows you to store more than one field into the index, which can be useful for composite properties, but is more complex to implement.I am not sure how to proceed using the TwoWayFieldBridge to address my need here. Any help is appreciated!@Entity (name = "JHI_USER_AD_ACCOUNT")@Indexed@IdClass(UserAdAccountId.class)@Getter@Setterpublic class UserAdAccount implements SearchableEntity, Serializable { //newly added id field with two way string bridge @DocumentId @Column(name = "ID") @FieldBridge(impl = UserAdAccoutPrimaryKeyBridge.class) private UserAdAccountId id; @Id @Column(name = "AD_ACCOUNT_ID") @GenericGenerator( name = "native", strategy = "native") @Field private Long adAccountId; @Id @Column(name = "USER_ID") @GenericGenerator( name = "native", strategy = "native") @Field private Long userId; @ManyToOne @JoinColumn(name = "USER_ID", referencedColumnName = "ID", updatable = false, insertable = false) @JsonIgnore private User user; @ManyToOne @JoinColumn(name = "AD_ACCOUNT_ID", referencedColumnName = "ID", updatable = false, insertable = false) @IndexedEmbedded(includePaths = "name") private AdAccount adAccount;}@Getter@Setter@EqualsAndHashCode(of = {"userId", "adAccountId"})public class UserAdAccountId implements Serializable { private Long userId; private Long adAccountId;}public class UserAdAccoutPrimaryKeyBridge implements TwoWayStringBridge { @Override public String objectToString(Object object) { UserAdAccountId userAdAccountId = (UserAdAccountId) object; StringBuilder buffer = new StringBuilder(); buffer.append(userAdAccountId.getUserId()).append("-").append(userAdAccountId.getAdAccountId()); return buffer.toString(); } @Override public Object stringToObject(String value) { String[] components = value.split("-"); UserAdAccountId userAdAccountId = new UserAdAccountId(); userAdAccountId.setUserId(Long.parseLong(components[0])); userAdAccountId.setAdAccountId(Long.parseLong(components[1])); return userAdAccountId; }} 解决方案 From the documentation:You can find an example implementation for a composite primary key on github:public class PersonPKBridge implements TwoWayFieldBridge, MetadataProvidingFieldBridge { private static final String FIRST_NAME_SUFFIX = "_content.firstName"; private static final String LAST_NAME_SUFFIX = "_content.lastName"; @Override public void configureFieldMetadata(String name, FieldMetadataBuilder builder) { builder.field( name + FIRST_NAME_SUFFIX, FieldType.STRING ) .field( name + LAST_NAME_SUFFIX, FieldType.STRING ); } @Override public Object get(String name, Document document) { PersonPK id = new PersonPK(); IndexableField field = document.getField( name + FIRST_NAME_SUFFIX ); id.setFirstName( field.stringValue() ); field = document.getField( name + LAST_NAME_SUFFIX ); id.setLastName( field.stringValue() ); return id; } @Override public String objectToString(Object object) { PersonPK id = (PersonPK) object; StringBuilder sb = new StringBuilder(); sb.append( id.getFirstName() ).append( " " ).append( id.getLastName() ); return sb.toString(); } @Override public void set(String name, Object value, Document document, LuceneOptions luceneOptions) { PersonPK id = (PersonPK) value; //store each property in a unique field luceneOptions.addFieldToDocument( name + FIRST_NAME_SUFFIX, id.getFirstName(), document ); luceneOptions.addFieldToDocument( name + LAST_NAME_SUFFIX, id.getLastName(), document ); //store the unique string representation in the named field luceneOptions.addFieldToDocument( name, objectToString( id ), document ); }}Alternatively, if you're certain the components of your ID don't contain a certain string, you will be able to use that string as a separator for the indexed form of your ID, and you'll be able to convert that indexed form back to the original ID. This means you can use the simpler TwoWayStringBridge and rely on concatenation/splitting:public class PersonPKBridge implements TwoWayStringBridge { @Override public String objectToString(Object object) { PersonPK id = (PersonPK) object; StringBuilder sb = new StringBuilder(); sb.append( id.getFirstName() ).append( " " ).append( id.getLastName() ); return sb.toString(); } @Override public Object stringToObject(String value) { String[] components = value.split(" "); PersonPK id = new PersonPK(); id.setFirstName( components[0] ); id.setLastName( components[1] ); return id; }} 这篇关于如何在休眠搜索中索引复合主键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-21 04:19