-->
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: Null-values in search result with one hit
PostPosted: Mon Jun 27, 2011 8:25 am 
Newbie

Joined: Mon Jul 12, 2010 5:41 am
Posts: 6
I perform a query using Hibernate Search / Lucene in the following way:

Code:
            final QueryParser parser = new MultiFieldQueryParser(
                    LuceneConstants.VERSION, mappedClassFields,
                    new StandardAnalyzer(LuceneConstants.VERSION));
            final org.apache.lucene.search.Query luceneQuery =
                    parser.parse(searchString);
            final org.hibernate.Query hibernateQuery =
                    fullTextSession.createFullTextQuery(
                            luceneQuery, mappedClasses);

            final List list = hibernateQuery.list();


This work well most of the time, but not when the search results in one hit. When I get a search result of one entity, the entity will be filled with null values, as if the entity was not initialized.

I've also stepped through the Hibernate Search code to determine what happens for these cases. From what I can tell, an EntityInfo object gets created from the Lucene index containing the correct values. Later into the process, an EntityKey object is also created using the correct values. Finally an empty proxy is created using these values, and the proxy is still empty when returned back to my code.

I've found a temporary workaround using this code:

Code:
            final List list = hibernateQuery.list();
            for (int i = 0; i < list.size(); i++) {
                final Object object = list.get(i);
                if (object instanceof HibernateProxy) {
                    list.set(i, ((HibernateProxy) object)
                            .getHibernateLazyInitializer().getImplementation());
                }
            }



I found by debugging that the lazy initalizer contained the original entity with its correct values. Although this code works, I would prefer not needing to do this.

After looking through the forums, this is the closest I could find, although the entity was correct set up in my code:
viewtopic.php?f=9&t=972543

Thanks,
Stig


Top
 Profile  
 
 Post subject: Re: Null-values in search result with one hit
PostPosted: Tue Jun 28, 2011 6:48 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Can you post your entity? Are you sure index and database are in sync?

--Hardy


Top
 Profile  
 
 Post subject: Re: Null-values in search result with one hit
PostPosted: Tue Jun 28, 2011 7:39 am 
Newbie

Joined: Mon Jul 12, 2010 5:41 am
Posts: 6
Here is the entity (three superclasses follow):

Code:
package com.wis.wisweb2.data.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.search.annotations.Boost;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
import org.springframework.web.bind.annotation.RequestMapping;

import com.wis.wisweb2.annotation.DocumentLead;
import com.wis.wisweb2.annotation.DocumentModule;
import com.wis.wisweb2.annotation.DocumentTitle;
import com.wis.wisweb2.intra.core.client.data.ModuleIdent;

@Entity
@Indexed
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@RequestMapping("/news/{id}/{title}")
@DocumentTitle("{title}")
@DocumentLead("{lead}")
@DocumentModule(ModuleIdent.NEWS)
@Table(name = "news")
public class News extends AbstractDocumentEntity {

    @Field(index = Index.TOKENIZED, store = Store.NO)
    @Boost(2.0f)
    private String title;
    @Field(index = Index.TOKENIZED, store = Store.NO)
    @Boost(2.0f)
    private String lead;
    @Field(index = Index.TOKENIZED, store = Store.NO)
    private String content;
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "publish_date")
    private Date publishDate;

    public News() {
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(final String title) {
        this.title = title;
    }

    public String getLead() {
        return lead;
    }

    public void setLead(final String lead) {
        this.lead = lead;
    }

    public String getContent() {
        return content;
    }

    public void setContent(final String content) {
        this.content = content;
    }

    public Date getPublishDate() {
        return publishDate;
    }

    public void setPublishDate(final Date publishDate) {
        this.publishDate = publishDate;
    }
}


Code:
package com.wis.wisweb2.data.entity;

import java.util.Calendar;

import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
* Base class for all document entities. Contains fields shared between all
* document tables.
*/
@MappedSuperclass
public abstract class AbstractDocumentEntity extends AbstractRevisionEntity {

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "created_by")
    private User createdBy;
    @Column(name = "created_date", nullable = true)
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar createdDate;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "modified_by")
    private User modifiedBy;
    @Column(name = "modified_date", nullable = true)
    @Temporal(TemporalType.TIMESTAMP)
    private Calendar modifiedDate;
    @Column(name = "revision_number", nullable = false)
    private int revisionNumber;

    public AbstractDocumentEntity() {
        // revisionNumber = 1;
    }

    public User getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(final User createdBy) {
        this.createdBy = createdBy;
    }

    public Calendar getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(final Calendar createdDate) {
        this.createdDate = createdDate;
    }

    public User getModifiedBy() {
        return modifiedBy;
    }

    public void setModifiedBy(final User modifiedBy) {
        this.modifiedBy = modifiedBy;
    }

    public Calendar getModifiedDate() {
        return modifiedDate;
    }

    public void setModifiedDate(final Calendar modifiedDate) {
        this.modifiedDate = modifiedDate;
    }

    @Override
    public int getRevisionNumber() {
        return revisionNumber;
    }

    public void setRevisionNumber(final int revisionNumber) {
        this.revisionNumber = revisionNumber;
    }
}


Code:
package com.wis.wisweb2.data.entity;

import javax.persistence.MappedSuperclass;

/**
* Placeholder for allowing simple entities to be transferred using GWT
* RequestFactory. These entities needs an id as well as a revision number.
*/
@MappedSuperclass
public abstract class AbstractRevisionEntity extends AbstractEntity {

    /**
     * Gets the static revision number. This method will always return "1".
     *
     * @return the revision number
     */
    public int getRevisionNumber() {
        return 1;
    }
}


Code:
package com.wis.wisweb2.data.entity;

import java.io.Serializable;
import java.util.Locale;
import java.util.Scanner;

import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

import com.wis.wisweb2.intra.core.client.dto.IdModelDtoTag;

/**
* Base class for all entities. Does also contain ident converters for GWT
* integration.
*/
@MappedSuperclass
public abstract class AbstractEntity implements Serializable, IdModelDtoTag {

    @Id
    @GeneratedValue
    private long id;

    public long getId() {
        return id;
    }

    public void setId(final long id) {
        this.id = id;
    }

    public String getIdString() {
        return String.valueOf(id);
    }

    public void setIdString(final String id) {
        final Scanner scanner = new Scanner(id);
        scanner.useLocale(Locale.ROOT);
        if (scanner.hasNextLong()) {
            this.id = scanner.nextLong();
        }
    }
}


I've deleted the full index and recreated it several times, but this error happens only when I get one result from the search. When I get two or more results, the entities are pulled out correctly.


Top
 Profile  
 
 Post subject: Re: Null-values in search result with one hit
PostPosted: Wed Jun 29, 2011 6:19 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Any chance that you can create a runnable testcase? Does it matter which single result query you execute?
Btw, have you tried w/ and w/o the caching option?


Top
 Profile  
 
 Post subject: Re: Null-values in search result with one hit
PostPosted: Thu Jun 30, 2011 1:54 am 
Newbie

Joined: Mon Jul 12, 2010 5:41 am
Posts: 6
I was preparing a testcase, and I found the problem while doing so. Hibernate Search had nothing to do with it after all. When reading data from the entity I was reading data using reflection in this special case. This did of course not work, as I was getting a javassist-enriched object back. After converting that routine to use introspection instead, it started to work.

I also set up the testcase to test what happens when two entities are returned from the search. I these cases, I get the pure beans back from Hibernate Search, and the reflection routine worked.


Top
 Profile  
 
 Post subject: Re: Null-values in search result with one hit
PostPosted: Thu Jun 30, 2011 3:57 am 
Hibernate Team
Hibernate Team

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


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.