Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 4.4.0.Final
    • Component/s: query
    • Labels:
      None
    • Environment:
      Hibernate ORM 4.2.7-SNAPSHOT, Javaassist 3.18.1-GA
    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • Last commented by a user?:
      true

      Description

      I just tried upgrading everything to the latest version and I ran into this blocker

      FullTextSession fts = Search.getFullTextSession(getSessionFactory().getCurrentSession());
          
       QueryBuilder qb = fts.getSearchFactory().buildQueryBuilder().forEntity(Usor.class).get();
       
       return (Long) fts.createFullTextQuery(qb.bool()
          .must(
             qb.keyword().onField("site.id").ignoreAnalyzer().matching(countrySite.getSite().getId()).createQuery()
          )
          .must(            
             qb.keyword().onField("location.country.countryCode").ignoreAnalyzer().matching(countrySite.getCountry().getCountryCode()).createQuery()   
          )
          .must(            
             qb.keyword().onField("role.label").ignoreAnalyzer().matching(UserRole.ROLE_COUNTRYLEADER).createQuery()   
          ).createQuery()
       )
       .setProjection("id")
       .setResultTransformer(new ProjectionFirstResultTransformer())
       .setCacheable(true)
       .setCacheRegion(CacheRegion.NEVERCHANGE)
       .uniqueResult();
      
      nl.msw.compraventa.exceptions.SearchException: org.hibernate.search.SearchException: Unable to find field role.label in nl.msw.project.model.user.Usor
      	at nl.msw.project.dao.hibernate.SearchFacetDaoHibernate.findUsersByFacet(SearchFacetDaoHibernate.java:702)
      [...]
      Caused by: org.hibernate.search.SearchException: Unable to find field role.label in nl.msw.project.model.user.Usor
      	at org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.objectToString(DocumentBuilderIndexedEntity.java:681)
      	at org.hibernate.search.query.dsl.impl.FieldContext.objectToString(FieldContext.java:86)
      	at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.buildSearchTerm(ConnectedMultiFieldsTermQueryBuilder.java:146)
      	at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.createQuery(ConnectedMultiFieldsTermQueryBuilder.java:100)
      	at org.hibernate.search.query.dsl.impl.ConnectedMultiFieldsTermQueryBuilder.createQuery(ConnectedMultiFieldsTermQueryBuilder.java:81)
      
      

      Needless to say, this worked in the past. Here's the configuration for the classes in question:

      Usor
      @Entity(name = "User2")
      @Table(name = "User")
      @org.hibernate.annotations.Table(appliesTo = "User", indexes={
      	@org.hibernate.annotations.Index(name="passwd",columnNames={"email","password"})
      })
      @Indexed
      @FullTextFilterDefs({
      	@FullTextFilterDef(name="wallFilter",impl=HibernateWallFilterFactory.class)
      })
      @AnalyzerDef(name = "userAnalyzer", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), filters = {
      	@TokenFilterDef(factory = StandardFilterFactory.class),
      	@TokenFilterDef(factory = ASCIIFoldingFilterFactory.class), 
      	@TokenFilterDef(factory = LowerCaseFilterFactory.class) 
      })
      @NaturalIdCache(region=CacheRegion.NATURAL)
      @Cache(usage=CacheConcurrencyStrategy.READ_WRITE,region=CacheRegion.USER)
      public class Usor{
      	
      	@ManyToMany(cascade=CascadeType.MERGE,fetch = FetchType.LAZY)
      	@JoinTable(name = "User_UserRoles", joinColumns = @JoinColumn(nullable = false), inverseJoinColumns = @JoinColumn(nullable = false))
      	@Fetch(FetchMode.SUBSELECT)
      	@BatchSize(size=10)
      	@Cache(usage=CacheConcurrencyStrategy.READ_WRITE,region=CacheRegion.USER)
      	@IndexedEmbedded(prefix="role.")
      	@JsonIgnore
      	public Set<UserRole> getRoles() {
      		return roles;
      	}
      
      UserRole
      @Entity
      @Immutable
      @Table(name="UserRole")
      @NaturalIdCache(region=CacheRegion.NATURAL)
      @Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,region=CacheRegion.USER)
      public class UserRole implements Comparable<UserRole>, Serializable,GrantedAuthority, IEntity{
      
      	@Column(length=30,nullable=false,unique=true,updatable=false)
      	@NaturalId
      	@Index(name="idxRoleLabel")
      	@Field(index=org.hibernate.search.annotations.Index.YES,store=Store.YES,analyze=Analyze.NO)
      	public String getLabel() {
      		return label;
      	}
      

        Issue Links

          Activity

          Hide
          Hardy Ferentschik added a comment -

          I totally agree with you. I don't think it's a good idea to change the logic in a bugfix release so applying Yoann's fix for now is what I would have suggested.

          Cool. So we agree to keep changes to a minimal. The one thing I don't like yet is that the whole if condition is very cryptic and implicit. AFAIU (see also comment on pull request) the condition occurs when I switch between one @IndexedEmbedded field/getter of a given entity to the next (provided there is one). Maybe instead of implicitly resetting we should make the code more explicit within initializeMemberLevelAnnotations. I think you might have meant this anyways when talking about "root entities" earlier. I give it a try whether this works and to see whether my theory is correct.

          +1 for waiting for Marc's feedback. Once we have a solution we will have to apply it to at least 4.5 and the 5.0 dev branch. Not sure whether this single issue requires another 4.4 point release. That's open for discussion.

          Show
          Hardy Ferentschik added a comment - I totally agree with you. I don't think it's a good idea to change the logic in a bugfix release so applying Yoann's fix for now is what I would have suggested. Cool. So we agree to keep changes to a minimal. The one thing I don't like yet is that the whole if condition is very cryptic and implicit. AFAIU (see also comment on pull request) the condition occurs when I switch between one @IndexedEmbedded field/getter of a given entity to the next (provided there is one). Maybe instead of implicitly resetting we should make the code more explicit within initializeMemberLevelAnnotations . I think you might have meant this anyways when talking about "root entities" earlier. I give it a try whether this works and to see whether my theory is correct. +1 for waiting for Marc's feedback. Once we have a solution we will have to apply it to at least 4.5 and the 5.0 dev branch. Not sure whether this single issue requires another 4.4 point release. That's open for discussion.
          Hide
          Sanne Grinovero added a comment -

          After the mailing list feedback, I've added 4.4 too as a target.

          Show
          Sanne Grinovero added a comment - After the mailing list feedback, I've added 4.4 too as a target.
          Hide
          Marc Schipperheyn added a comment -

          Yeah, tried it. Seems to work fine.

          Show
          Marc Schipperheyn added a comment - Yeah, tried it. Seems to work fine.
          Hide
          Hardy Ferentschik added a comment -

          Yeah, tried it. Seems to work fine.

          Thanks Marc Schipperheyn

          Show
          Hardy Ferentschik added a comment - Yeah, tried it. Seems to work fine. Thanks Marc Schipperheyn
          Hide
          Hardy Ferentschik added a comment -

          HSEARCH-1467 explains the need of rewriting the indexed embedded parsing algorithm

          Show
          Hardy Ferentschik added a comment - HSEARCH-1467 explains the need of rewriting the indexed embedded parsing algorithm

            People

            • Votes:
              1 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development