-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: hibernate search: score and fetch join
PostPosted: Wed Jun 16, 2010 9:03 pm 
Beginner
Beginner

Joined: Thu Nov 20, 2003 10:16 pm
Posts: 28
Location: Los Angeles, CA
I am currently having two issues with when iterating over the results of a full-text query using Hibernate Search 3.2 / Hibernate 3.5.1.Final.

1) Although I get back the hydrated objects, the score in each result row is NaN.

2) Although I attempt to set 'join fetch' for the collection of title entities, when I iterate over the resulting physicians, I still incur a separate select for each titles collection.

My basic model is:

Physician <- 1 - many -> PhysicianTitles

Any ideas?

Michael

Code:
  org.apache.lucene.queryParser.QueryParser parser = new QueryParser(Version.LUCENE_29, "lastName", analyzer);

      String                         luceneQueryString = createLuceneQueryString(criteria);
      org.apache.lucene.search.Query luceneQuery       = parser.parse(luceneQueryString);

      org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery);

      fullTextQuery.setProjection(FullTextQuery.THIS, FullTextQuery.SCORE);

      // Optimize fetch.
      Criteria fetchingStrategy = fullTextSession.createCriteria(Physician.class);
      fetchingStrategy.setFetchMode("titles", FetchMode.JOIN);
      fullTextQuery.setCriteriaQuery(fetchingStrategy);

      fullTextQuery.setReadOnly(true);
      fullTextQuery.setFirstResult(range.getOffset());
      fullTextQuery.setMaxResults(range.getSize());

      if ((sortBy != null) && !sortBy.isEmpty())
      {
        fullTextQuery.setSort(LuceneToolkit.toSort(DAOHelper.toLuceneSortBy(sortBy)));
      }

      List<Object[]> results = fullTextQuery.list();

      for (Object[] result : results)
      {
        Physician physician = (Physician) result[0];

        // Normalize score.
        Number score = (Number) result[1];

        // Populate search-result.
        PhysicianSearchResultDTO searchResult = PhysicianConverter.toDTO(physician);

        if (!score.equals(Float.NaN))
        {
          searchResult.setScore(score.floatValue());
        }

        resultChunk.add(searchResult);
      }


Top
 Profile  
 
 Post subject: Re: hibernate search: score and fetch join
PostPosted: Thu Jun 17, 2010 5:32 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Hi,

regarding question 1 - this is a bug. The Lucene behavior has changed with Lucene 2.9. I created HSEARCH-545. The problem is that the score is not calculated per default anymore when using a custom Sort.

About question 2 I am not so sure. Maybe it would help if you post your annotated entities. I assume you have SQL debug trace turned on. It would help to see that as well.

--Hardy


Top
 Profile  
 
 Post subject: Re: hibernate search: score and fetch join
PostPosted: Thu Jun 17, 2010 1:46 pm 
Beginner
Beginner

Joined: Thu Nov 20, 2003 10:16 pm
Posts: 28
Location: Los Angeles, CA
Thanks, Hardy. For the second issue, here are the classes involved (simplified to just the members - I'm doing field-level annotation):

Physician
Code:
@Entity @Table(name = "MDS_PHYSICIAN")
@Indexed
public class Physician extends PersistentEntity
{
  //~ Statics ------------------------------------------------------------------

  static private final long serialVersionUID = 1934834917682898622L;

  //~ Members ------------------------------------------------------------------

  @Basic @Column(name = "PHYS_ADMIN_EMAIL_ADDR")
  private String        adminEmailAddress;

  @OneToMany(mappedBy = "physician")
  @IndexedEmbedded
  private Set<PhysicianAffiliation> affiliations;

  @OneToMany(mappedBy = "physician")
  @IndexedEmbedded 
  private Set<PhysicianExpertise> areasOfExpertise;

  @Column(name = "PHYS_BIRTH_DT")
  @Temporal(TemporalType.TIMESTAMP)
  private Date birthDate;

  @Basic @Column(name = "PHYS_DIRECTORSHIP")
  private String        directorship;

  @OneToMany(mappedBy = "physician")
  private Set<PhysicianEducationProgram> educationPrograms;

  @Basic @Column(name = "PHYS_EMAIL_ADDR")
  private String        emailAddress;

  @Basic @Column(name = "PHYS_FIRST_NM", nullable = false)
  @Fields({
   @Field(index = Index.TOKENIZED, store = Store.NO),
    @Field(name = "firstName_sort", index = Index.UN_TOKENIZED, store = Store.NO)
  })
  private String        firstName;

  @JoinColumn(name = "PHYS_GENDER_CD")
  @ManyToOne(fetch = FetchType.LAZY)
  private MdsCode genderCode;

  @Column(name = "PHYS_ID", nullable = false)
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Id
  private Long id;

  @OneToMany(mappedBy = "physician")
  private Set<PhysicianInsurancePlan> insurancePlans;

  @Basic @Column(name = "PHYS_LAST_NM", nullable = false)
  @Fields({
   @Field(index = Index.TOKENIZED, store = Store.NO),
    @Field(name = "lastName_sort", index = Index.UN_TOKENIZED, store = Store.NO)
  }) 
  private String        lastName;

  @Column(name = "PHYS_MAINT_DT")
  @Temporal(TemporalType.TIMESTAMP)
  private Date maintDate;

  @Basic @Column(name = "PHYS_NO")
  private String        mdNumber;

  @Basic @Column(name = "PHYS_MI")
  private String        middleInitial;

  @Basic @Column(name = "PHYS_NPI_NO")
  private String        npiNumber;

  @OneToMany(mappedBy = "physician")
  private Set<PhysicianOffice> offices;

  @Column(name = "PHYS_ON_STAFF_DT")
  @Temporal(TemporalType.TIMESTAMP)
  private Date onStaffDate;

  @JoinColumn(name = "PHYS_RANK_CD")
  @ManyToOne(fetch = FetchType.LAZY)
  private MdsCode rankCode;

  @OneToMany(mappedBy = "physician")
  @IndexedEmbedded 
  private Set<PhysicianSpecialty> specialties;

  @JoinColumn(name = "PHYS_STATUS_CD")
  @ManyToOne(fetch = FetchType.LAZY)
  private MdsCode statusCode;

  @Column(name = "PHYS_STATUS_FROM_DT")
  @Temporal(TemporalType.TIMESTAMP)
  private Date statusFromDate;

  @OneToMany(mappedBy = "physician")
  private Set<PhysicianTitle> titles;

  @Basic @Column(name = "PHYS_YR_BEGIN_PRACTICE")
  private int yearBeganPractice;


PhysicianTitle
Code:
@Entity @Table(name = "MDS_PHYSICIAN_TITLE")
public class PhysicianTitle extends PersistentEntity
{
  //~ Statics ------------------------------------------------------------------

  static private final long serialVersionUID = 1934834917682898622L;

  //~ Members ------------------------------------------------------------------

  @Basic @Column(name = "PHYS_TITLE_DESC", nullable = false)
  private String description;

  @Column(name = "PHYS_TITLE_ID", nullable = false)
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Id
  private Long id;

  @JoinColumn(name = "PHYS_ID")
  @ManyToOne(fetch = FetchType.LAZY)
  private Physician physician;
}

PersistentEntity
Code:
@MappedSuperclass
public abstract class PersistentEntity implements Cloneable, Serializable
{
  //~ Statics ------------------------------------------------------------------

  static private final Log LOG = LogFactory.getLog(PersistentEntity.class);

  static private final long serialVersionUID = -7935676908641580483L;

  //~ Members ------------------------------------------------------------------

  @Column(name = "ACTIVE_FLG", nullable = false, length = 1)
  @Type(type = "yes_no")
  @Field(index=Index.UN_TOKENIZED, store=Store.NO)
  private Boolean active;

  @Basic @Column(name = "CREATED_BY", length = 30, nullable = false)
  private String createdBy;

  @Column(name = "CREATE_DT", nullable = false)
  @Temporal(TemporalType.TIMESTAMP)
  private Date createdDate;

  @Basic @Column(name = "MODIFIED_BY", length = 30, nullable = false)
  private String modifiedBy;

  @Column(name = "MODIFIED_DT", nullable = false)
  @Temporal(TemporalType.TIMESTAMP)
  private Date modifiedDate;

  //~ Constructors -------------------------------------------------------------

  public PersistentEntity()
  {
    this.active = Boolean.FALSE;
  }

  //~ Methods ------------------------------------------------------------------

  public abstract Long getId();

  public abstract void setId(Long id);
}


And the generated SQL:
Code:
Hibernate:
    select
        this_.PHYS_ID as PHYS1_6_0_,
        this_.ACTIVE_FLG as ACTIVE2_6_0_,
        this_.CREATED_BY as CREATED3_6_0_,
        this_.CREATE_DT as CREATE4_6_0_,
        this_.MODIFIED_BY as MODIFIED5_6_0_,
        this_.MODIFIED_DT as MODIFIED6_6_0_,
        this_.PHYS_ADMIN_EMAIL_ADDR as PHYS7_6_0_,
        this_.PHYS_BIRTH_DT as PHYS8_6_0_,
        this_.PHYS_DIRECTORSHIP as PHYS9_6_0_,
        this_.PHYS_EMAIL_ADDR as PHYS10_6_0_,
        this_.PHYS_FIRST_NM as PHYS11_6_0_,
        this_.PHYS_GENDER_CD as PHYS20_6_0_,
        this_.PHYS_LAST_NM as PHYS12_6_0_,
        this_.PHYS_MAINT_DT as PHYS13_6_0_,
        this_.PHYS_NO as PHYS14_6_0_,
        this_.PHYS_MI as PHYS15_6_0_,
        this_.PHYS_NPI_NO as PHYS16_6_0_,
        this_.PHYS_ON_STAFF_DT as PHYS17_6_0_,
        this_.PHYS_RANK_CD as PHYS21_6_0_,
        this_.PHYS_STATUS_CD as PHYS22_6_0_,
        this_.PHYS_STATUS_FROM_DT as PHYS18_6_0_,
        this_.PHYS_YR_BEGIN_PRACTICE as PHYS19_6_0_
    from
        MDS_PHYSICIAN this_
    where
        (
            this_.PHYS_ID in (
                ?, ?
            )
        )

Hibernate:
    select
        titles0_.PHYS_ID as PHYS8_6_1_,
        titles0_.PHYS_TITLE_ID as PHYS1_1_,
        titles0_.PHYS_TITLE_ID as PHYS1_4_0_,
        titles0_.ACTIVE_FLG as ACTIVE2_4_0_,
        titles0_.CREATED_BY as CREATED3_4_0_,
        titles0_.CREATE_DT as CREATE4_4_0_,
        titles0_.MODIFIED_BY as MODIFIED5_4_0_,
        titles0_.MODIFIED_DT as MODIFIED6_4_0_,
        titles0_.PHYS_TITLE_DESC as PHYS7_4_0_,
        titles0_.PHYS_ID as PHYS8_4_0_
    from
        MDS_PHYSICIAN_TITLE titles0_
    where
        titles0_.PHYS_ID=?


Thanks for any help.

Michael


Top
 Profile  
 
 Post subject: Re: hibernate search: score and fetch join
PostPosted: Fri Jun 18, 2010 5:53 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Turns out there is yet another problem. The projection loader ignores the fetch mode - HSEARCH-546.


Top
 Profile  
 
 Post subject: Re: hibernate search: score and fetch join
PostPosted: Fri Jun 18, 2010 7:24 pm 
Beginner
Beginner

Joined: Thu Nov 20, 2003 10:16 pm
Posts: 28
Location: Los Angeles, CA
Thanks, Hardy. Any idea when these might be fixed?


Top
 Profile  
 
 Post subject: Re: hibernate search: score and fetch join
PostPosted: Mon Jun 21, 2010 5:13 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
I would say for the next release, but I cannot make any promises.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.