为什么Hibernate Search需要花费很多时间来构建索引?

时间:2012-07-02 14:35:39

标签: java java-ee hibernate-search

我正在尝试通过hibernate搜索FullTextSession.createIndexer().startAndWait()构建一个lucene索引 但即使对于非常少的测试数据,它也不会结束。

这是我的代码

@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");

    }

}

实体

@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>

还有一点我的记录:

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

我不是为什么,但在我看来,hibernate搜索以某种方式进入无限循环。欢迎任何帮助。

1 个答案:

答案 0 :(得分:3)

如果您还没有弄明白,请检查您允许的最大连接数,因为质量索引器使用了大量连接。例如,如果您使用像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>

尝试将initialPoolSize设置为3,将maxPoolSize设置为100或更高,然后重试。

希望有所帮助!