问题
I've configured with hibernate-search annotation (4.1.1 version library) my class Intervento. So, I'm using jpa and in my case i can omit @DocumentId
but I have a composite primary key...
@IdClass(it.domain.InterventoPK.class)
@Entity
@Indexed
@AnalyzerDef(name = "interventongram", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class, params = {
@Parameter(name = "words", value = "lucene/dictionary/stopwords.txt"),
@Parameter(name = "ignoreCase", value = "true"),
@Parameter(name = "enablePositionIncrements", value = "true")
}),
@TokenFilterDef(factory = ItalianLightStemFilterFactory.class),
@TokenFilterDef(factory = SynonymFilterFactory.class, params = {
@Parameter(name = "synonyms", value = "lucene/dictionary/synonyms.txt"),
@Parameter(name = "expand", value = "true")
}),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
@Parameter(name = "language", value = "Italian")
})
})
@Table(name = "intervento", catalog = "gestionale")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(namespace = "Clinigo/it/domain", name = "Intervento")
@XmlRootElement(namespace = "Clinigo/it/domain")
public class Intervento implements Serializable {
private static final long serialVersionUID = 1L;
/**
*/
@Column(name = "idintervento", nullable = false)
@Basic(fetch = FetchType.EAGER)
@Id
@XmlElement
Integer idintervento;
/**
*/
@Column(name = "lingua_idlingua", nullable = false)
@Basic(fetch = FetchType.EAGER)
@Id
@XmlElement
Integer linguaIdlingua;
/**
*/
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "version", nullable = false)
@Basic(fetch = FetchType.EAGER)
@XmlElement
Calendar version;
...
I'm getting....can you help me?
ERROR: HSEARCH000058: HSEARCH000116: Unexpected error during MassIndexer operation java.lang.ClassCastException: it.domain.InterventoPK cannot be cast to java.lang.Integer at org.hibernate.type.descriptor.java.IntegerTypeDescriptor.unwrap(IntegerTypeDescriptor.java:36) at org.hibernate.type.descriptor.sql.IntegerTypeDescriptor$1.doBind(IntegerTypeDescriptor.java:57) at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:92) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:305) at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:300) at org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1891) at org.hibernate.loader.Loader.bindParameterValues(Loader.java:1862) at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1737) at org.hibernate.loader.Loader.doQuery(Loader.java:828) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289) at org.hibernate.loader.Loader.doList(Loader.java:2447) at org.hibernate.loader.Loader.doList(Loader.java:2433) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2263) at org.hibernate.loader.Loader.list(Loader.java:2258) at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:122) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1535) at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:374) at org.hibernate.search.batchindexing.impl.IdentifierConsumerEntityProducer.loadList(IdentifierConsumerEntityProducer.java:150) at org.hibernate.search.batchindexing.impl.IdentifierConsumerEntityProducer.loadAllFromQueue(IdentifierConsumerEntityProducer.java:117) at org.hibernate.search.batchindexing.impl.IdentifierConsumerEntityProducer.run(IdentifierConsumerEntityProducer.java:94) at org.hibernate.search.batchindexing.impl.OptionallyWrapInJTATransaction.run(OptionallyWrapInJTATransaction.java:84) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)
回答1:
Hibernate Search does not handle composite id classes used with @IdClass. A workaround would be to use @EmbeddedId and place idintervento and linguaIdlingua into InterventoPK.
Seems also that you asked the same question on the Hibernate Search forum - https://forum.hibernate.org/viewtopic.php?f=9&t=1024512
回答2:
You can convert your custom object / composite key to Lucene Understandable format by using bridges. For example for a class
@Entity
@Indexed
public class Person {
@EmbeddedId @DocumentId Embedded id
@FieldBridge(impl=PersonPkBridge.class)
private PersonPK id;
...
}
You can write the bridge as like this. These codes are from the book 'Hibernate Search In Action'. I found it very helpful.
回答3:
Does your class declared as composite key (it.domain.InterventoPK.class, as declared via @IdClass class-level annotation) only contain two integer fields? Since you've also annotated two such Integer fields with @Id on your Intervento class, the composite key class must only contain those fields and they must have the same name. Also that composite PK class needs to be Serializable. From the docs:
"map multiple properties as @Id properties and declare an external class to be the identifier type. This class, which needs to be Serializable, is declared on the entity via the @IdClass annotation. The identifier type must contain the same properties as the identifier properties of the entity: each property name must be the same, its type must be the same as well if the entity property is of a basic type, its type must be the type of the primary key of the associated entity if the entity property is an association (either a @OneToOne or a @ManyToOne)."
http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/
(search "Composite identifier" in page)
回答4:
I had already replied on your question on the Hibernate forums, but to complete my suggestion:
An alternative to changing your mapping is that you add add a @DocumentId on a new getter, and return any object - maybe even a string - which is a unique composite of the two ids components. (This requires defining mapping on getters and setters however)
When using JPA you can avoid specifying the @DocumentId but you don't have to, you can still use the annotation to override the definition of identity which you want to apply on the index mapping.
来源:https://stackoverflow.com/questions/12796497/hibernate-search-does-not-work-woth-composite-primary-key-using-idclass