Hibernate搜索-自定义网桥值未更新

Hibernate搜索-自定义网桥值未更新,hibernate,lucene,hibernate-search,Hibernate,Lucene,Hibernate Search,发件人: 我有: @Indexed @Entity public class TParent implements java.io.Serializable { ..... private Set<TChild> TChildSet = new HashSet<TChild>(0); @ContainedIn @FieldBridge(impl = CollectionCountBridge.class) @Field(analyze = Analyze.NO) @

发件人: 我有:

@Indexed
@Entity
public class TParent  implements java.io.Serializable {

.....
private Set<TChild> TChildSet = new HashSet<TChild>(0);

@ContainedIn
@FieldBridge(impl = CollectionCountBridge.class)
@Field(analyze = Analyze.NO)
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="TParent")
public Set<TChild> getTChildSet() {
   return this.TChildSet;
}
多亏了唐·罗比,我申请了这座桥

public class CollectionCountBridge extends IntegerBridge {

   @Override
   public String objectToString(Object object) {
     if (object == null || (!(object instanceof Collection))) {
         return null;
     }
     Collection<?> coll = (Collection<?>) object;
     int size = coll.size();
     System.out.println("col.size(): " + size);
     return super.objectToString(size);
  }

}
现在

当我添加一个新的TChild时,将执行CustomBridge代码。我希望在添加TChild时看到订单的变化

我可以看到TChild计数增加了(根据CustomBridge代码中的System.out.println()

但是,查询没有对它们进行正确排序。索引第一次构建时的原始排序顺序保持不变。添加新的TChild对排序顺序没有影响。 我想索引没有更新,但我不确定

任何帮助或指点都会很好

非常感谢

约翰

编辑
直接的问题是索引中的值没有更新。这可以通过Luke看到。

我认为您的问题是,您将数字(整数)索引为字符串,但您希望进行数字排序

你有两个选择。如果您坚持使用字符串方法,则需要创建填充字符串(例如,如果您知道您的元素从未超过100个,那么您将填充所有数字,如003等)。这样一来,词法顺序将表现为数字顺序

可能更好的选择是将计数作为数字字段进行索引。这样,排序将自动为数字。类似于(未经测试):

公共类集合CountFieldBridge{
无效集(字符串名称、对象值、文档、LuceneOptions LuceneOptions){
if(object==null | |(!(集合的对象实例))){
返回null;
}
Collection coll=(Collection)对象;
int size=coll.size();
luceneOptions.addNumericFieldToDocument(名称、值、文档);;
}
}

我认为您的问题在于您将数字(整数)索引为字符串,但您希望进行数字排序

你有两个选择。如果您坚持使用字符串方法,则需要创建填充字符串(例如,如果您知道您的元素从未超过100个,那么您将填充所有数字,如003等)。这样一来,词法顺序将表现为数字顺序

可能更好的选择是将计数作为数字字段进行索引。这样,排序将自动为数字。类似于(未经测试):

公共类集合CountFieldBridge{
无效集(字符串名称、对象值、文档、LuceneOptions LuceneOptions){
if(object==null | |(!(集合的对象实例))){
返回null;
}
Collection coll=(Collection)对象;
int size=coll.size();
luceneOptions.addNumericFieldToDocument(名称、值、文档);;
}
}

问题

在实体中,对不是DB表字段的索引字段执行更新,然后保存实体不会导致索引更新。(保存实体并更新为DB表字段的索引字段将导致索引自动更新)

解决方案

(简单地)手动更新索引

public static void addTChild() {
    Session session = null;
    try {
        session = HibernateUtil.getSession();
        session.beginTransaction();
        TParent tParent = (TParent)session.get(TParent.class, 6L);
        TChild tChild = new TChild(tParent, "Auto added " + new Date().toString(), 'y');
        Long id  = (Long)session.save(tChild);
        tChild = (TChild)session.get(TChild.class, id);
        tParent.getTChildSet().add(tChild);
        session.save(tParent);

        /*
         * Manually update the index.
         * Necessary due to fact that the index field updated
         * is not a DB table field and hence will not cause an index update
         */
        FullTextSession fullTextSession = Search.getFullTextSession(session);
        fullTextSession.index(tParent);

        session.getTransaction().commit();
    } catch (Exception ex) {
        session.getTransaction().rollback();
        ex.printStackTrace();
    } finally{
        if(session != null) {
            session.close();
        }
    }
}
实体:

/*
 * TParent
 */
@ContainedIn
@FieldBridge(impl = CollectionCountBridge.class)
@Field(analyze = Analyze.NO, store = Store.YES, name = "cCount")
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="TParent")
public List<TChild> getTChildSet() {
    return this.TChildSet;
}

这就是我所能确定的。

问题所在

在实体中,对不是DB表字段的索引字段执行更新,然后保存实体不会导致索引更新。(保存实体并更新为DB表字段的索引字段将导致索引自动更新)

解决方案

(简单地)手动更新索引

public static void addTChild() {
    Session session = null;
    try {
        session = HibernateUtil.getSession();
        session.beginTransaction();
        TParent tParent = (TParent)session.get(TParent.class, 6L);
        TChild tChild = new TChild(tParent, "Auto added " + new Date().toString(), 'y');
        Long id  = (Long)session.save(tChild);
        tChild = (TChild)session.get(TChild.class, id);
        tParent.getTChildSet().add(tChild);
        session.save(tParent);

        /*
         * Manually update the index.
         * Necessary due to fact that the index field updated
         * is not a DB table field and hence will not cause an index update
         */
        FullTextSession fullTextSession = Search.getFullTextSession(session);
        fullTextSession.index(tParent);

        session.getTransaction().commit();
    } catch (Exception ex) {
        session.getTransaction().rollback();
        ex.printStackTrace();
    } finally{
        if(session != null) {
            session.close();
        }
    }
}
实体:

/*
 * TParent
 */
@ContainedIn
@FieldBridge(impl = CollectionCountBridge.class)
@Field(analyze = Analyze.NO, store = Store.YES, name = "cCount")
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="TParent")
public List<TChild> getTChildSet() {
    return this.TChildSet;
}

这就是我所能确定的。

Hmmm。。谢谢,我试过了,但还是不高兴。同样的问题。无论如何,我的测试用例只有不到10个项,所以即使整数是字符串,它们也会继续以单位数正确排序。我分析了卢克的索引。我可以看到,在添加新的TChild时,没有更新子计数。我已经完成了session.save(tChild)和session.update(tParent),将新的tChild添加到列表中。嗯,我认为您确实应该创建子实例,将其添加到父实例中,在子实例中设置父实例,然后在父实例中调用session.save。由于级联保存,所有内容都将被保存。使用当前的方法,我认为您不会因为重新索引父对象而得到回调。可能会发布关于如何更新和持久化实体的代码。非常感谢您的输入。你说得对,TParent确实需要更新。但是我发现(这就是问题所在)在保存TParent之前,仅仅将TChild添加到TChildSet是不够的。TParent的一些其他属性,在保存TParent之前,也需要更新用字段注释的属性。也就是说,TParent有一个“title”(字符串)成员,用字段注释。如果我将“title”设置为某物并保存,则TChildSet计数将在索引中更新。如果我没有更改“title”,则索引中的TChildSet计数值不会更新。Hmmm。。谢谢,我试过了,但还是不高兴。同样的问题。无论如何,我的测试用例只有不到10个项,所以即使整数是字符串,它们也会继续以单位数正确排序。我分析了卢克的索引。我可以看到,在添加新的TChild时,没有更新子计数。我已经完成了session.save(tChild)和session.update(tParent),将新的tChild添加到列表中。嗯,我认为您确实应该创建子实例,将其添加到父实例中,在子实例中设置父实例,然后在父实例中调用session.save。由于级联保存,所有内容都将被保存。使用当前的方法,我认为您不会因为重新索引父对象而得到回调。可能会发布关于如何更新和持久化实体的代码。非常感谢您的输入。你说得对,TParent确实需要更新。但是我发现(这就是问题所在)在保存TParent之前,仅仅将TChild添加到TChildSet是不够的。TParent的一些其他属性,用需要upda的字段注释
/*
 * TParent
 */
@ContainedIn
@FieldBridge(impl = CollectionCountBridge.class)
@Field(analyze = Analyze.NO, store = Store.YES, name = "cCount")
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="TParent")
public List<TChild> getTChildSet() {
    return this.TChildSet;
}
/*
 * TChild
 */
 @IndexedEmbedded
 @ManyToOne(fetch=FetchType.LAZY)
 @JoinColumn(name="parent_id", nullable=false)
 public TParent getTParent() {
    return this.TParent;
 }