У меня есть следующая модель данных:
@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;
...
}
Как видите, EntryDetail и EntryDetailCtx имеют одно и то же свойство "receiveName", у меня возникла проблема при поиске значения, скажем "IndividualName1", с помощью следующего кода:
@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;
}
Таким образом, после индексации сущностей и попытки выполнить поиск по «receiveName», которое является общим для моей базы данных, скажем «Jhon», я получаю следующее исключение ..
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
Я прочитал множество форумов поиска в спящем режиме и даже книгу «Поиск в спящем режиме» без каких-либо положительных результатов, кто-нибудь подскажет мне идеи или возможные решения этой проблемы?
Спасибо
РЕДАКТИРОВАТЬ : Обнаружено, что проблема заключалась в том, что EntryDetail и EntryDetailCtx могут иметь одинаковые идентификаторы (поскольку оба находятся в разных таблицах ..), однако, поскольку @documentID
наследуется из AbstractRecord может дублироваться в обеих таблицах, во время выполнения поиска возникает проблема ... Теперь у меня есть дополнительная проблема, и это следующее:
@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;
...
}
Мне нужно, чтобы uniqueTableKey и recordNumber были моими новыми @ documentID для поиска, однако поиск в Hibernate допускает только 1 documentId, справка?