问题
I am trying to build a lucene index through hibernate searchFullTextSession.createIndexer().startAndWait()
but even for very little test data it won't end.
Here is my code
@Component("hibernateSearchMassIndexerService")
public class HibernateSearchMassIndexerServiceImpl implements HibernateSearchMassIndexerService {
public static final Logger log = LoggerFactory
.getLogger(HibernateSearchMassIndexerServiceImpl.class);
@Override
@Transactional
public void buildSearchIndex(Session session) {
log.debug("Indexing entities");
FullTextSession fullTextSession = Search.getFullTextSession(session);
try {
fullTextSession.createIndexer().startAndWait();
} catch (InterruptedException e) {
log.debug("Interrupted indexing process");
}
log.debug("Ended indexing of entities");
}
}
Entities
@Entity
@Indexed(index = "causa_penal")
@Table(name = "causas_penales")
public class CausaPenal implements Serializable {
private static final long serialVersionUID = 1L;
@Basic
@Column(name = "anio_causa")
@Field
private Integer annioCausa;
@OneToMany(mappedBy = "causaPenal")
@ContainedIn
@OrderBy
private List<AudienciaOral> audienciasOrales;
@ManyToMany(cascade = CascadeType.ALL)
private List<DefensorPenal> defensoresPenales;
@OneToMany(cascade = CascadeType.ALL)
private List<DelitoConfigurado> delitosConfigurados;
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id")
@DocumentId
private Integer id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "causapenal_imputados")
@IndexedEmbedded(depth = 1)
private List<ParteMaterial> imputados;
@ManyToMany(cascade = CascadeType.ALL)
private List<MinisterioPublico> ministeriosPublicos;
@Basic
@Column(name = "numero_causa")
@Field
private Integer numeroCausa;
@Version
@Column(name = "opt_lock")
private Integer version;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "causapenal_victimas")
@IndexedEmbedded(depth = 1)
private List<ParteMaterial> victimas;
public CausaPenal() {
}
public CausaPenal(Integer id, Integer version, Integer numeroCausa, Integer annioCausa,
List<DelitoConfigurado> delitosConfigurados, List<ParteMaterial> victimas,
List<ParteMaterial> imputados, List<MinisterioPublico> ministeriosPublicos,
List<DefensorPenal> defensoresPenales, List<AudienciaOral> audienciasOrales) {
super();
this.id = id;
this.version = version;
this.numeroCausa = numeroCausa;
this.annioCausa = annioCausa;
this.delitosConfigurados = delitosConfigurados;
this.victimas = victimas;
this.imputados = imputados;
this.ministeriosPublicos = ministeriosPublicos;
this.defensoresPenales = defensoresPenales;
this.audienciasOrales = audienciasOrales;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof CausaPenal)) {
return false;
}
CausaPenal o = (CausaPenal) obj;
return new EqualsBuilder().append(this.numeroCausa, o.numeroCausa)
.append(this.annioCausa, o.annioCausa).isEquals();
}
public Integer getAnnioCausa() {
return this.annioCausa;
}
public List<AudienciaOral> getAudienciasOrales() {
return this.audienciasOrales;
}
public List<DefensorPenal> getDefensoresPenales() {
return this.defensoresPenales;
}
public List<DelitoConfigurado> getDelitosConfigurados() {
return this.delitosConfigurados;
}
public Integer getId() {
return this.id;
}
public List<ParteMaterial> getImputados() {
return this.imputados;
}
public List<MinisterioPublico> getMinisteriosPublicos() {
return this.ministeriosPublicos;
}
public Integer getNumeroCausa() {
return this.numeroCausa;
}
public Integer getVersion() {
return this.version;
}
public List<ParteMaterial> getVictimas() {
return this.victimas;
}
@Override
public int hashCode() {
return new HashCodeBuilder(13, 33).append(this.numeroCausa).append(this.annioCausa)
.toHashCode();
}
public void setAnnioCausa(Integer annioCausa) {
this.annioCausa = annioCausa;
}
public void setAudienciasOrales(List<AudienciaOral> audienciasOrales) {
this.audienciasOrales = audienciasOrales;
}
public void setDefensoresPenales(List<DefensorPenal> defensoresPenales) {
this.defensoresPenales = defensoresPenales;
}
public void setDelitosConfigurados(List<DelitoConfigurado> delitosConfigurados) {
this.delitosConfigurados = delitosConfigurados;
}
public void setId(Integer id) {
this.id = id;
}
public void setImputados(List<ParteMaterial> imputados) {
this.imputados = imputados;
}
public void setMinisteriosPublicos(List<MinisterioPublico> ministeriosPublicos) {
this.ministeriosPublicos = ministeriosPublicos;
}
public void setNumeroCausa(Integer numeroCausa) {
this.numeroCausa = numeroCausa;
}
public void setVersion(Integer version) {
this.version = version;
}
public void setVictimas(List<ParteMaterial> victimas) {
this.victimas = victimas;
}
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
@Entity
@Indexed(index = "partes_materiales")
@Table(name = "partes_materiales")
public class ParteMaterial implements Serializable {
private static final long serialVersionUID = 1L;
@Basic
@Column(name = "alias")
private String alias;
@Basic
@Column(name = "apellido_materno")
@Field
private String apellidoMaterno;
@Basic
@Column(name = "apellido_paterno")
@Field
private String apellidoPaterno;
@Basic
@Column(name = "descripcion_persona_moral")
private String descripcionPersonaMoral;
@ElementCollection
@JoinTable(name = "partes_materiales_domicilios")
private List<Domicilio> domicilios;
@Basic
@Column(name = "edad")
private Integer edad;
@Enumerated(EnumType.STRING)
@Column(name = "estado_civil")
private EstadoCivil estadoCivil;
@Temporal(TemporalType.DATE)
@Column(name = "fecha_nacimiento")
private Date fechaNacimiento;
@Enumerated(EnumType.STRING)
@Column(name = "genero")
private Genero genero;
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "id")
@DocumentId
private Integer id;
@Basic
@Column(name = "identificacion_personal")
private String identificacion;
@Basic
@Column(name = "idioma")
private String idioma;
@Basic
@Column(name = "lugar_nacimiento")
private String lugarNacimiento;
@Basic
@Column(name = "nombres")
@Field
private String nombres;
@Basic
@Column(name = "profesion_oficio")
private String profesionOrOficio;
@Version
@Column(name = "opt_lock")
private Integer version;
public ParteMaterial() {
}
public ParteMaterial(String alias, String apellidoMaterno, String apellidoPaterno,
String descripcionPersonaMoral, List<Domicilio> domicilios, Integer edad,
EstadoCivil estadoCivil, Date fechaNacimiento, Genero genero, Integer id,
String identificacion, String idioma, String lugarNacimiento, String nombres,
String profesionOrOficio, Integer version) {
super();
this.alias = alias;
this.apellidoMaterno = apellidoMaterno;
this.apellidoPaterno = apellidoPaterno;
this.descripcionPersonaMoral = descripcionPersonaMoral;
this.domicilios = domicilios;
this.edad = edad;
this.estadoCivil = estadoCivil;
this.fechaNacimiento = fechaNacimiento;
this.genero = genero;
this.id = id;
this.identificacion = identificacion;
this.idioma = idioma;
this.lugarNacimiento = lugarNacimiento;
this.nombres = nombres;
this.profesionOrOficio = profesionOrOficio;
this.version = version;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (!(obj instanceof ParteMaterial)) {
return false;
}
ParteMaterial o = (ParteMaterial) obj;
return new EqualsBuilder().append(this.nombres, o.nombres)
.append(this.apellidoPaterno, o.apellidoPaterno)
.append(this.apellidoMaterno, o.apellidoMaterno)
.append(this.descripcionPersonaMoral, o.descripcionPersonaMoral).isEquals();
}
public String getAlias() {
return this.alias;
}
public String getApellidoMaterno() {
return this.apellidoMaterno;
}
public String getApellidoPaterno() {
return this.apellidoPaterno;
}
public String getDescripcionPersonaMoral() {
return this.descripcionPersonaMoral;
}
public List<Domicilio> getDomicilios() {
return this.domicilios;
}
public Integer getEdad() {
return this.edad;
}
public EstadoCivil getEstadoCivil() {
return this.estadoCivil;
}
public Date getFechaNacimiento() {
return this.fechaNacimiento;
}
public Genero getGenero() {
return this.genero;
}
public Integer getId() {
return this.id;
}
public String getIdentificacion() {
return this.identificacion;
}
public String getIdioma() {
return this.idioma;
}
public String getLugarNacimiento() {
return this.lugarNacimiento;
}
public String getNombres() {
return this.nombres;
}
public String getProfesionOrOficio() {
return this.profesionOrOficio;
}
public Integer getVersion() {
return this.version;
}
@Override
public int hashCode() {
return new HashCodeBuilder(31, 147).append(this.nombres).append(this.apellidoPaterno)
.append(this.apellidoMaterno).append(this.descripcionPersonaMoral).toHashCode();
}
public void setAlias(String alias) {
this.alias = alias;
}
public void setApellidoMaterno(String apellidoMaterno) {
this.apellidoMaterno = apellidoMaterno;
}
public void setApellidoPaterno(String apellidoPaterno) {
this.apellidoPaterno = apellidoPaterno;
}
public void setDescripcionPersonaMoral(String descripcionPersonaMoral) {
this.descripcionPersonaMoral = descripcionPersonaMoral;
}
public void setDomicilios(List<Domicilio> domicilios) {
this.domicilios = domicilios;
}
public void setEdad(Integer edad) {
this.edad = edad;
}
public void setEstadoCivil(EstadoCivil estadoCivil) {
this.estadoCivil = estadoCivil;
}
public void setFechaNacimiento(Date fechaNacimiento) {
this.fechaNacimiento = fechaNacimiento;
}
public void setGenero(Genero genero) {
this.genero = genero;
}
public void setId(Integer id) {
this.id = id;
}
public void setIdentificacion(String identificacion) {
this.identificacion = identificacion;
}
public void setIdioma(String idioma) {
this.idioma = idioma;
}
public void setLugarNacimiento(String lugarNacimiento) {
this.lugarNacimiento = lugarNacimiento;
}
public void setNombres(String nombres) {
this.nombres = nombres;
}
public void setProfesionOrOficio(String profesionOrOficio) {
this.profesionOrOficio = profesionOrOficio;
}
public void setVersion(Integer version) {
this.version = version;
}
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
Spring config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:util="http://www.springframework.org/schema/util"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
<property name="initialSize" value="${datasource.poolInitialSize}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.current_session_context_class">
mx.gob.jgtjo.apps.schedule.web.conversation.ConversationalCurrentSessionContext
</prop>
<prop key="hibernate.dialect">${org.hibernate.dialect.dialectmysqlInno}</prop>
<prop key="hibernate.hbm2ddl.auto">${org.hibernate.ddl.mode}</prop>
<prop key="hibernate.connection.release_mode">${org.hibernate.transaction.release_mode}</prop>
<prop key="hibernate.search.default.directory_provider">${org.hibernate.search.directoryprovidr}</prop>
<prop key="hibernate.search.default.indexBase">
${org.hibernate.search.index.base_directory}
</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
<property name="dataSource" ref="dataSource" />
<property name="hibernateManagedSession" value="true" />
</bean>
<tx:annotation-driven order="0" transaction-manager="transactionManager" />
<context:component-scan base-package="mx.gob.jgtjo.apps.schedule.dao.hibernate" />
</beans>
Hibernate Config
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="jgtjoSessionFactory">
<!--Entity -->
<mapping class="mx.gob.jgtjo.apps.schedule.model.AudienciaOral" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.CausaPenal" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.DefensorPenal" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Delito" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.EventoAudiencia" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Juez" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.MinisterioPublico" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.ParteMaterial" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Sala" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.TipoAudiencia" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.User" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.Rol" />
<mapping class="mx.gob.jgtjo.apps.schedule.model.DelitoConfigurado" />
</session-factory>
</hibernate-configuration>
And a little bit of my logging:
09:33:18,767 [ssIndexerServiceImpl] (tp-bio-8080"-exec-10) DEBUG : Indexing entities
09:33:18,773 [orphicIndexHierarchy] (tp-bio-8080"-exec-10) TRACE : Targeted indexed classes for [class java.lang.Object]: [class mx.gob.jgtjo.apps.schedule.model.CausaPenal, class mx.gob.jgtjo.apps.schedule.model.ParteMaterial]
09:33:18,774 [MassIndexerImpl ] (tp-bio-8080"-exec-10) DEBUG : Targets for indexing job: [class mx.gob.jgtjo.apps.schedule.model.CausaPenal, class mx.gob.jgtjo.apps.schedule.model.ParteMaterial]
09:33:18,819 [orphicIndexHierarchy] (tp-bio-8080"-exec-10) TRACE : Targeted indexed classes for [class mx.gob.jgtjo.apps.schedule.model.CausaPenal, class mx.gob.jgtjo.apps.schedule.model.ParteMaterial]: [class mx.gob.jgtjo.apps.schedule.model.CausaPenal, class mx.gob.jgtjo.apps.schedule.model.ParteMaterial]
09:33:18,869 [Workspace ] (tp-bio-8080"-exec-10) TRACE : IndexWriter opened using batch configuration
09:33:18,869 [PurgeAllWorkDelegate] (tp-bio-8080"-exec-10) TRACE : purgeAll Lucene index using IndexWriter for type: class mx.gob.jgtjo.apps.schedule.model.CausaPenal
09:33:18,889 [Workspace ] (tp-bio-8080"-exec-10) TRACE : IndexWriter opened using batch configuration
09:33:18,890 [PurgeAllWorkDelegate] (tp-bio-8080"-exec-10) TRACE : purgeAll Lucene index using IndexWriter for type: class mx.gob.jgtjo.apps.schedule.model.ParteMaterial
09:33:18,891 [OptimizeWorkDelegate] (tp-bio-8080"-exec-10) TRACE : optimize Lucene index: class mx.gob.jgtjo.apps.schedule.model.CausaPenal
09:33:18,893 [OptimizeWorkDelegate] (tp-bio-8080"-exec-10) TRACE : optimize Lucene index: class mx.gob.jgtjo.apps.schedule.model.ParteMaterial
09:33:18,940 [WrapInJTATransaction] ( collectionsloader-2) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,940 [WrapInJTATransaction] ( collectionsloader-3) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,940 [WrapInJTATransaction] ( collectionsloader-2) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,944 [nsumerEntityProducer] (hIndexingWorkspace-2) TRACE : created
09:33:18,946 [WrapInJTATransaction] ( collectionsloader-4) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,947 [nsumerEntityProducer] (hIndexingWorkspace-2) TRACE : created
09:33:18,948 [WrapInJTATransaction] (arch: entityloader-1) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,932 [WrapInJTATransaction] ( collectionsloader-1) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,932 [WrapInJTATransaction] ( collectionsloader-1) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,950 [WrapInJTATransaction] (arch: entityloader-2) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,951 [WrapInJTATransaction] ( collectionsloader-3) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,974 [IdentifierProducer ] (hIndexingWorkspace-2) TRACE : created
09:33:18,948 [nsumerEntityProducer] (arch: entityloader-1) TRACE : started
09:33:18,973 [WrapInJTATransaction] ( collectionsloader-4) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,951 [nsumerEntityProducer] (hIndexingWorkspace-1) TRACE : created
09:33:18,950 [nsumerEntityProducer] (arch: entityloader-2) TRACE : started
09:33:18,975 [WrapInJTATransaction] (: identifierloader-1) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,978 [nsumerEntityProducer] (hIndexingWorkspace-1) TRACE : created
09:33:18,978 [WrapInJTATransaction] (arch: entityloader-1) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,979 [nsumerEntityProducer] (arch: entityloader-1) TRACE : started
09:33:18,977 [IdentifierProducer ] (: identifierloader-1) TRACE : started
09:33:18,979 [IdentifierProducer ] (hIndexingWorkspace-1) TRACE : created
09:33:18,988 [WrapInJTATransaction] (arch: entityloader-2) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:18,989 [nsumerEntityProducer] (arch: entityloader-2) TRACE : started
09:33:19,049 [WrapInJTATransaction] (: identifierloader-1) TRACE : TransactionFactory does not require a TransactionManager: don't wrap in a JTA transaction
09:33:19,050 [IdentifierProducer ] (: identifierloader-1) TRACE : started
I do not why but it seems to me that hibernate search is somehow entering a infinite loop. Any help is welcome.
回答1:
In case you haven't figured it out already, check your maximum allowed connections, as the mass indexer uses a lot of connections. For example, if you use a pooled data source like c3p0:
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="username"/>
<property name="password" value="password"/>
<property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:@my.dbserver.com:1521:PRODUCTION"/>
<property name="initialPoolSize" value="1"/>
<property name="minPoolSize" value="1"/>
<property name="maxPoolSize" value="10"/>
</bean>
Try setting initialPoolSize to 3 and maxPoolSize 100 or higher and try again.
Hope that helps!
来源:https://stackoverflow.com/questions/11295800/why-hibernate-search-takes-so-much-time-to-build-a-index