Pergunta

I have the following data model:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractRecord
    implements Serializable
{
    ...
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "id", nullable = false)
    @DocumentId
    private Integer id;
    ...

}

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@NamedQueries(...)
})
public abstract class AbstractEntryDetail
    extends AbstractRecord
    implements Serializable
{
...
}

@Indexed(index = "entryDetailIndex")
@Entity
@Table(name = "nacha_entry_detail")
@NamedQueries(...)
})
public class EntryDetail
    extends AbstractEntryDetail
    implements Serializable
{
    ...
    @Field(index = Index.TOKENIZED, store = Store.NO)
    @Column(name = "receiver_name", nullable = false)
    private String receiverName;
    ...

}

@Indexed(index = "entryDetailCtxIndex")
@Entity
@Table(name = "nacha_entry_detail_ctx")
@NamedQueries(...)
public class EntryDetailCtx
    extends AbstractEntryDetail
    implements Serializable
{
    ...
    @Field(index = Index.TOKENIZED, store = Store.NO)
    @Column(name = "receiver_name", nullable = false)
    private String receiverName;
    ...
}

As you can see, EntryDetail and EntryDetailCtx share the same property "receiverName", I am having a problem when searching for a value say "IndividualName1" through the following code:

@Stateless
@TransactionAttribute(TransactionAttributeType.MANDATORY)
@RolesAllowed({PermissionUtil.SEARCH_LIST,
    PermissionUtil.LUCENE_INDEX
})
public class SearchFacade
{
    ...
    @RolesAllowed(PermissionUtil.SEARCH_LIST)
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public List<AbstractRecord> doSearch(String stringToFind)
    {
        List<AbstractRecord> result = null;

        // Test Search for specific values of an Abstract Record
        // Aim to return the number of retreived results
        EntityManager em = emf.createEntityManager();
        FullTextEntityManager fullTextEntityManager =
            org.hibernate.search.jpa.Search.getFullTextEntityManager(em);
        String[] fields =
            // Fields to be reviewed
            new String[]
            {   ....,"receiverName",.... 
            };

        //Create a multi-field Lucene query
        StandardAnalyzer stdAnalyzer = new StandardAnalyzer(Version.LUCENE_30);
        MultiFieldQueryParser parser =
            new MultiFieldQueryParser(Version.LUCENE_30, fields, stdAnalyzer);
        org.apache.lucene.search.Query query = null;

        try
        {
            query = parser.parse(stringToFind);
        }
        catch (ParseException ex)
        {
            Logger.getLogger(SearchFacade.class.getName()).log(Level.SEVERE, null, ex);
        }

        long time1 = System.currentTimeMillis();

        // Wrap Lucene query in a javax.persistence.Query
        javax.persistence.Query persistenceQuery =
            fullTextEntityManager.createFullTextQuery(query);
        // Execute search
        //HAVING PROBLEMS HERE
        result = (List<AbstractRecord>) persistenceQuery.getResultList();

        long time2 = System.currentTimeMillis();
        Logger.getLogger(SearchFacade.class.getName())
              .log(
            Level.FINER, "Hibernate Search Execution time: {0}",
            Long.toString(time2 - time1));

        //em.getTransaction().commit();
        em.close();

        return result;
    }

So after indexing the entities and trying to perform a search on a "receiverName" that is shared on my data base, say "Jhon" I get the following exception..

Caused by: org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: com.xxx.ejb.core.entity.nacha.EntryDetailCtx (loaded object was of wrong class class com.xxx.ejb.core.entity.nacha.EntryDetail)
    at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1391)
    at org.hibernate.loader.Loader.getRow(Loader.java:1344)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611)
    at org.hibernate.loader.Loader.doQuery(Loader.java:829)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
    at org.hibernate.loader.Loader.doList(Loader.java:2533)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
    at org.hibernate.loader.Loader.list(Loader.java:2271)
    at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
    at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
    at org.hibernate.search.engine.ObjectLoaderHelper.initializeObjects(ObjectLoaderHelper.java:116)
    at org.hibernate.search.engine.MultiClassesQueryLoader.executeLoad(MultiClassesQueryLoader.java:124)
    at org.hibernate.search.engine.AbstractLoader.load(AbstractLoader.java:70)
    at org.hibernate.search.query.FullTextQueryImpl.list(FullTextQueryImpl.java:317)
    at org.hibernate.search.jpa.impl.FullTextQueryImpl.getResultList(FullTextQueryImpl.java:137)
    at com.paysett.ejb.core.facade.SearchFacade.doSearch(SearchFacade.java:130)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at org.glassfish.ejb.security.application.EJBSecurityManager.runMethod(EJBSecurityManager.java:1056)
    at org.glassfish.ejb.security.application.EJBSecurityManager.invoke(EJBSecurityManager.java:1128)
    at com.sun.ejb.containers.BaseContainer.invokeBeanMethod(BaseContainer.java:5292)
    at com.sun.ejb.EjbInvocation.invokeBeanMethod(EjbInvocation.java:615)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:797)
    at com.sun.ejb.EjbInvocation.proceed(EjbInvocation.java:567)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.doAround(SystemInterceptorProxy.java:157)
    at com.sun.ejb.containers.interceptors.SystemInterceptorProxy.aroundInvoke(SystemInterceptorProxy.java:139)
    at sun.reflect.GeneratedMethodAccessor525.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:616)
    at com.sun.ejb.containers.interceptors.AroundInvokeInterceptor.intercept(InterceptorManager.java:858)
    at com.sun.ejb.containers.interceptors.AroundInvokeChainImpl.invokeNext(InterceptorManager.java:797)
    at com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:367)
    at com.sun.ejb.containers.BaseContainer.__intercept(BaseContainer.java:5264)
    at com.sun.ejb.containers.BaseContainer.intercept(BaseContainer.java:5252)
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:190)
    ... 52 more

I have read throughly many hibernate search forums and even Hibernate Search in Action book without any positive results, ca anyone light me up with ideas or possible solutions to this problem? Thanks

EDIT: Found out that the problem was that EntryDetail and EntryDetailCtx both can have same ID's (Because both are on different tables..) however since @documentID which is inherited from AbstractRecord can be duplicated in both tables at search execution time generates the problem... Now I have an additional problem and it is the following:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractRecord
    implements Serializable
{
    //~ Instance variables ---------------------------------------------------------------
/** SERIALID */ public static final String SERIALID = "hyzmfgSwl5hsDbxZIitNILMT2/eiPYJErJcqIMun3/PVy3SbbiQie4k9lLnL450BhwL8EnUMyc+wrhgZtUBTdG9/YUuJ+ni/FRAdRGzTy7UrQI7opbrYRYehDUwj3hg9";
    /** id for this record. */
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "id", nullable = false)
    private Integer id;

    /** line number for this record. */
    @Field(index=Index.UN_TOKENIZED, store=Store.NO)
    @Column(name = "record_number", nullable = false)
    private Integer recordNumber;

    /** record types for this record. */
    @Field(index=Index.UN_TOKENIZED, store=Store.NO)
    @Column(name = "record_type", nullable = false)
    private Integer recordType;

    /** Current status for this record. */
    @Field(index=Index.UN_TOKENIZED, store=Store.NO)
    @Column(name = "record_status", nullable = false)
    @Enumerated(EnumType.ORDINAL)
    private RecordStatus recordStatus;

    /** unique table key for the file. */
    @Field(index=Index.UN_TOKENIZED, store=Store.NO)
    @Column(name = "unique_table_key", nullable = false)
    private String uniqueTableKey;

    ...
}

I need uniqueTableKey and recordNumber to be my new @documentID's for the search, however Hibernate search only allows 1 documentId, help?

Foi útil?

Solução

Possible solutions to this problem are the following: EmbeededID and Idclass

And then annotating as @DocumentId any of the above chosen solutions

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top