Why Hibernate Search takes so much time to build a Index? - java

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.

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!

Related

Why am I getting message about failed altering table while I am only mapping classes to tables at test launch?

At the start of tests, I am mapping many tables from Oracle DB to java classes. Just now I am running only one test query and it runs OK. (Thank SO!)
I have turned on the messages and at the stage of context creation and tables mapping I see not only many successful table findings but in the end, several messages such as:
TST-[2020/12/02 23:58:53.715] hbm2ddl.SchemaUpdate HHH000388: Unsuccessful: alter table CIS_LOKAL_ROLE_AAA add KOD_LOKAL_ROLA_AAA varchar2(10 char) not null
TST-[2020/12/02 23:58:53.715] hbm2ddl.SchemaUpdate ORA-01758: table must be empty to add mandatory (NOT NULL) column
TST-[2020/12/02 23:58:53.881] hbm2ddl.SchemaUpdate HHH000388: Unsuccessful: alter table P01_OPRAVNENI add constraint FK_c0cufehvbvpf9y3dh0fcjrhak foreign key (ID_OBJEKTU) references R01_RIZENI
TST-[2020/12/02 23:58:53.881] hbm2ddl.SchemaUpdate ORA-02298: cannot validate (SPR.FK_C0CUFEHVBVPF9Y3DH0FCJRHAK) - parent keys not found
Why does hibernate want to alter tables at the time of mapping?
Please, note, that there are questions about the similar messages here on SO, but they touch situations when the tables really are to be altered and fail. While I don't want to alter them, the only query is about a counting query, and that is successful and comes after the problems I am writing about.
testng class:
#Test//(enabled = false)
#ContextConfiguration(locations={ "classpath:beans_sets/UhradyForIns.xml"/* , "classpath:beans_sets/mvc-config.xml"*/})
#TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
#DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class OdeslatJakobyAutomatickyUhraduTest extends TestBaseWithProperties {
private static final Logger log = LoggerFactory.getLogger(OdeslatJakobyAutomatickyUhraduTest.class);
#Autowired( required = true )
U01UhradaBaseJpaDaoForTesting dao;
#Transactional
#Test
public void odeslat(){
if(dao == null){
Assert.fail("Null context.");
}
dao.setRecordsForSending();
Reporter.log(new String("Number of uhrady to send = "+dao.countUhradyToSend()));
//List<U01Uhrada> uhrady = dao.findUhradyProPoslani();
}
}
public class U01UhradaBaseJpaDaoForTesting {
#PersistenceContext(unitName="SprUnit")
protected EntityManager em;
void setRecordsForSending(){
}
long countUhradyToSend(){
QU01Uhrada uh = QU01Uhrada.u01Uhrada;
JPAQuery jq = new JPAQuery(em);
jq.from(uh);
jq.where(uh.preposlano.eq(U01UhradaPreposlanoEnum.K_PREPOSLANI.asKod()));
return jq.count();
}
}
public class TestBaseWithProperties extends AbstractTestNGSpringContextTests {
{
//---------------------------------- setting paths
// absolute path up to main-app
String mainApp = System.getProperty("user.dir");
String apv = mainApp.substring(0, mainApp.lastIndexOf("\\"));
System.setProperty("main.app", mainApp);
System.setProperty("main.web.webinf", apv + "/main-web/src/main/webapp/WEB-INF");
System.setProperty("spr.root.dir", mainApp + "/work");
// -------------------------------------- setting DB
System.setProperty("database.driver", "oracle.jdbc.driver.OracleDriver");
System.setProperty("database.url", "jdbc:oracle:thin:#oradb2.companyname.com:1534:INPD12");
System.setProperty("database.user", "user");
System.setProperty("database.password", "pass");
}
}
UhradyForIns.xml:
<import resource="classpath:META-INF/spring/spr-properties.xml" />
<!-- Database setting -->
<!--<context:property-placeholder location="classpath:beans_sets/database-test.properties"/>-->
<bean id="dataSourceBean"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.user}"/>
<property name="password" value="${database.password}"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="file:${main.app}/src/test/resources/beans_sets/persistence-spr-test.xml"/>
<property name="persistenceUnitName" value="SprUnit"/>
<property name="dataSource" ref="dataSourceBean"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true"/>
<property name="generateDdl" value="true" />
</bean>
</property>
</bean>
<!-- Automatic Transaction Participation-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="U01UhradaBaseJpaDaoForTesting" class="amcssz.spr.srv.main.jobs.U01UhradaBaseJpaDaoForTesting"/>
persistence-spr-test.xml
<persistence-unit name="SprUnit" transaction-type="RESOURCE_LOCAL" >
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/spr-db</jta-data-source>
<class>amcssz.spr.srv.main.entity.P01Opravneni</class>
....
<class>amcssz.spr.srv.main.entity.cis.CisLokalRoleAaa</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<!-- Scan for annotated classes and Hibernate mapping XML files -->
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.max_fetch_depth" value="3" />
<property name="hibernate.show_sql" value="true" />
</properties>
</persistence-unit>
The entities of the problem tables:
#Entity
#Table(name="CIS_LOKAL_ROLE_AAA")
public class CisLokalRoleAaa extends AbstractCisEntity implements Serializable {
private static final long serialVersionUID = -1302716162506083142L;
#Id //that column exists in the table
#Column(name="KOD_LOKAL_ROLA_AAA", unique=true, nullable=false, length=10)
private String kodLokalRole;
#Column(name="KOD_PRACOVISTE", length=10)
private String kodPracoviste;
public CisLokalRoleAaa() {
}
public String getKodLokalRole() {
return kodLokalRole;
}
public void setKodLokalRole(String kodLokalRole) {
this.kodLokalRole = kodLokalRole;
}
public String getKodPracoviste() {
return kodPracoviste;
}
public void setKodPracoviste(String kodPracoviste) {
this.kodPracoviste = kodPracoviste;
}
}
#Entity
#Table(name="P01_OPRAVNENI")
#Inheritance(strategy = InheritanceType.SINGLE_TABLE)
#DiscriminatorColumn(name = "KOD_TYP_OBJEKTU", discriminatorType = DiscriminatorType.STRING)
public class P01Opravneni extends AbstractUpdateable implements Serializable {
private static final long serialVersionUID = -3009052816433258266L;
#Id
#SequenceGenerator(name="P01_OPRAVNENI_IDR02OPRAVNENIRIZENI_GENERATOR", sequenceName="SEQ_P01_OPRAVNENI")
#GeneratedValue(strategy=GenerationType.SEQUENCE, generator="P01_OPRAVNENI_IDR02OPRAVNENIRIZENI_GENERATOR")
#Column(name="ID_P01_OPRAVNENI", unique=true, nullable=false, precision=22)
private Long idP01Opravneni;
#Temporal( TemporalType.TIMESTAMP)
#Column(name="DATINS")
private Date datins;
#Column(name="JE_AKTUALNI", nullable=false, precision=1)
private Boolean jeAktualni;
#Column(name="VYMAHAC", nullable=false, length=44)
private String vymahac;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="KOD_TYP_OBJEKTU", referencedColumnName="KOD_OBJEKT",nullable=false, insertable=false, updatable=false)
private CisObjekt cisObjekt;
#Column(name="KOD_TYP_OBJEKTU",nullable=false, insertable=false,updatable=false)
private String kodTypObjektu;
#Column(name="ID_OBJEKTU", nullable=false)
private Long idObjektu;
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="KOD_PRACOVISTE", insertable=false, updatable=false)
private CisPracovisteCssz cisPracovisteCssz;
#Column(name="KOD_PRACOVISTE", precision=10)
private String kodPracoviste;
#Column(name="prevzato_do")
private Date prevzatoDo;
public Long getIdObjektu() {
return idObjektu;
}
public void setIdObjektu(Long idObjektu) {
this.idObjektu = idObjektu;
}
public String getKodTypObjektu() {
return kodTypObjektu;
}
public void setKodTypObjektu(String kodTypObjektu) {
this.kodTypObjektu = kodTypObjektu;
}
public P01Opravneni() {
}
public Long getIdP01Opravneni() {
return idP01Opravneni;
}
public void setIdP01Opravneni(Long idP02Opravneni) {
this.idP01Opravneni = idP02Opravneni;
}
public Date getDatins() {
return datins;
}
public void setDatins(Date datins) {
this.datins = datins;
}
public Boolean getJeAktualni() {
return this.jeAktualni;
}
public void setJeAktualni(Boolean jeAktualni) {
this.jeAktualni = jeAktualni;
}
public String getVymahac() {
return this.vymahac;
}
public void setVymahac(String vymahac) {
this.vymahac = vymahac;
}
public CisObjekt getCisObjekt() {
return this.cisObjekt;
}
public void setCisObjekt(CisObjekt cisObjekt) {
this.cisObjekt = cisObjekt;
}
public CisPracovisteCssz getCisPracovisteCssz() {
return this.cisPracovisteCssz;
}
public void setCisPracovisteCssz(CisPracovisteCssz cisPracovisteCssz) {
this.cisPracovisteCssz = cisPracovisteCssz;
}
public String getKodPracoviste() {
return kodPracoviste;
}
public void setKodPracoviste(String kodPracoviste) {
this.kodPracoviste = kodPracoviste;
}
public Date getPrevzatoDo() {
return prevzatoDo;
}
public void setPrevzatoDo(Date prevzatoDo) {
this.prevzatoDo = prevzatoDo;
}
}

Hibernate One-to-many mapping

I am new to hibernate , trying to learn one to many relationship , code is executing without any error but it only creating tables not inserting values on it . I want to establish one to many relationship between Employee and his assigned task . One employee can have multiple task.
Employee.java
#Entity
public class Employee {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String name;
#OneToMany
private Set<Task> taklist = new HashSet<Task>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Task> getTaklist() {
return taklist;
}
public void setTaklist(Set<Task> taklist) {
this.taklist = taklist;
}
}
Task.java
#Entity
public class Task {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int taskid;
private String taskname;
public int getTaskid() {
return taskid;
}
public void setTaskid(int taskid) {
this.taskid = taskid;
}
public String getTaskname() {
return taskname;
}
public void setTaskname(String taskname) {
this.taskname = taskname;
}
}
hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- Assume test is the database name -->
<property name="hibernate.connection.url">
jdbc:mysql://localhost/hibernate
</property>
<property name="hibernate.connection.username">
root
</property>
<property name="hibernate.connection.password">
root
</property>
<property name="connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create</property>
<mapping class="com.sumeet.onetomany.Employee"></mapping>
<mapping class="com.sumeet.onetomany.Task"></mapping>
</session-factory>
</hibernate-configuration>
App.java
package com.sumeet.onetomany;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class App {
public static void main(String args[]){
SessionFactory factory = new Configuration().configure().buildSessionFactory();
Session session = factory.openSession();
Employee emp = new Employee();
emp.setName("Arun");
Task task = new Task();
task.setTaskname("Office Work");
Task task2 = new Task();
task2.setTaskname("Home Work");
emp.getTaklist().add(task);
session.beginTransaction();
session.save(emp);
session.close();
}
}
You need to commit Transaction
Transaction tx = session.beginTransaction();
session.save(emp);
tx.commit(); // Need to commit transaction
session.close();

how to ignore a field in entity class for create table in mysql database?

I have a simple hibernate sample that have an entity class. I add a field to entity class that i don't want to create a column for that field in table of database. how can i do that?
my Entity class:
#Entity
#Table(name = "person")
public class PersonEntity {
private Long id;
private String emailEntity;
private String nameEntity;
private String familyEntity;
private String cityEntity;
private String phoneEntity;
private Long orgId;
private String province;
#Id
#GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#Column(name = "email")
public String getEmailEntity() {
return emailEntity;
}
public void setEmailEntity(String emailEntity) {
this.emailEntity = emailEntity;
}
#Column(name = "name")
public String getNameEntity() {
return nameEntity;
}
public void setNameEntity(String nameEntity) {
this.nameEntity = nameEntity;
}
#Column(name = "last_name")
public String getFamilyEntity() {
return familyEntity;
}
public void setFamilyEntity(String familyEntity) {
this.familyEntity = familyEntity;
}
#Column(name = "city")
public String getCityEntity() {
return cityEntity;
}
public void setCityEntity(String cityEntity) {
this.cityEntity = cityEntity;
}
#Column(name = "phone")
public String getPhoneEntity() {
return phoneEntity;
}
public void setPhoneEntity(String phoneEntity) {
this.phoneEntity = phoneEntity;
}
#Column(name = "org_id")
public Long getOrgId() {
return orgId;
}
public void setOrgId(Long orgId) {
this.orgId = orgId;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
hibernate.cfg.xml:
<?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>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/emailDB</property>
<property name="connection.username">root</property>
<property name="connection.password">123</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<!--<mapping class="net.viralpatel.hibernate.Employee"/>-->
<!--<mapping class="net.viralpatel.hibernate.PersonEntity"/>-->
<mapping class="organizationsTab.PersonEntity"/>
<mapping class="organizationsTab.OrgEntity"/>
</session-factory>
</hibernate-configuration>
'province' field is an auxiliary field and I don't want to create a column for that in table. how can i do that?
Annotate the field with #Transient annotation See more here
Every non static non transient property (field or method depending on the access type) of an entity is considered persistent, unless you annotate it as #Transient.
public transient int counter; //transient property
private String firstname; //persistent property
So you can use #Transient annotation on the property you do not wish to create a column for in database.

Hibernate 4 lazy loading doesn't work

I am working on a web application using spring 3 and hibernate 4.
I am having trouble lazy-loading a set of granted permissions of a group to which a user belongs.
When a user object is retrieved from the database, its Group object doesn't have any permissions even though user.getGroup().getPermissions() is invoked explicitly.
I noticed that in debug mode, if I mouse-over the User object and then navigate to the Group object inside the User object, and then navigate to its permissions, I can see its type is shown as PersistentSet, and expanding it will load permissions properly. But in non-debug mode, permissions are never lazy-loaded. What am I missing here? Thanks in advance.
Here are the relationships among the entities:
Users have an one-to-many relationship with groups, and groups have a many-to-many relationship with permissions.
Here's the definition of the UserDaoImpl class
#Repository
#Transactional
public class UserDaoImpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;
private Session getSession() {
return sessionFactory.getCurrentSession();
}
#Override
public User get(String username) {
Session session = getSession();
User user = (User) session.createCriteria(User.class).add(Restrictions.eq("username", username)).uniqueResult();
Group g = user.getGroup();
// calling g.getGrantedPermissions() doesn't load any permission
Set<Permission> permissions = g.getGrantedPermissions();
return user;
}
}
Here's the definition of the Permission class
#Entity
public class Permission {
#Id
#GeneratedValue
private Long id;
#Column
private String name;
#Column
private String description;
public Permission()
{
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Here's the definition of the Group class
#Entity
#Table(name="\"Group\"")
public class Group {
public static final String ROLE_VALID_USER = "ROLE_VALID_USER";
#Id
#GeneratedValue
private Long id;
#Column
private String description;
#Column
private String role;
#ManyToMany
#JoinTable(name = "granted_permission",
joinColumns = {#JoinColumn(name = "GROUP_ID", nullable = false, updatable = false) },
inverseJoinColumns = { #JoinColumn(name = "PERMISSION_ID", nullable = false, updatable = false) })
private Set<Permission> grantedPermissions;
public Group()
{
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Set<Permission> getGrantedPermissions() {
return grantedPermissions;
}
public void setGrantedPermissions(Set<Permission> grantedPermissions) {
this.grantedPermissions = grantedPermissions;
}
}
Here's the definition of the User class
#Entity
public class User {
#Id
#Column(name="USERNAME")
private String username;
#Column(name="PASSWORD")
private String password;
#Transient
private final boolean enabled = true;
#Column
private String name;
#Column(name="EMAIL")
private String email;
#Column(name="PHONE")
private String phone;
#ManyToOne
private Group group;
#ManyToOne
#JoinColumn(name="ORIGINAL_BRANCH_ID")
private Branch originalBranch;
#ManyToOne
#JoinColumn(name="ID_OF_RESPONSIBLE_BRANCH")
private Branch responsibleBranch;
public User()
{
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return group.getRole();
}
public boolean isEnabled() {
return enabled;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
public Branch getOriginalBranch() {
return originalBranch;
}
public void setOriginalBranch(Branch originalBranch) {
this.originalBranch = originalBranch;
}
public Branch getResponsibleBranch() {
return responsibleBranch;
}
public void setResponsibleBranch(Branch responsibleBranch) {
this.responsibleBranch = responsibleBranch;
}
}
Here's the persistence configuration:
<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<tx:annotation-driven />
<context:annotation-config />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<context:component-scan base-package="net.acme.prs" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="mysqlDataSource" />
<property name="packagesToScan" value="net.acme.prs" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQL5InnoDBDialect
</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="mysqlDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/prs" />
<property name="username" value="" />
<property name="password" value="" />
</bean>
</beans>
I cannot understand what is your problem because you haven't mentioned any error you encountered. If you simply found there was no SQL to fetch the grantedPermissions, it is what lazy-fetching is about: It is only fetched when it is accessed, and if it is not accessed, it won't be fetched.
The reason you see it being fetched during debug, is because when you are inspecting the grantedPermissions in debugger, it is accessing that property, which will trigger the lazy fetching. However, for non-debug mode, if you have no code accessing that property, no fetching is precisely what it supposed to do.
If what you are asking is, you have code in non-debug mode that will access grantedPermissions but lazy fetching failed when it is accessed, then it is due to the access is out of transaction: Hibernate needs to have an active Session to have lazy fetching happening. If the lazy-fetching happens out of the transaction, it will fail because there is no opened Session. You should revisit your design by considering
Scope of transaction: instead of having transaction around the DAO, you should put transaction boundary in a proper unit-of-work level: maybe your app service, or controller
Do proper join fetch/eager fetch, so that no lazy-fetching happens outside the transaction
EclipseLink, which is another JPA implementation, allows lazy-fetch after session is ended.
Follow http://docs.oracle.com/javaee/5/api/javax/persistence/FetchType.html
Example : If you want to auto load "grantedPermissions" in "Group", you have to change your annotation to #ManyToMany(fetch = FetchType.EAGER)

Hibernate Spatial: Type org.hibernatespatial.GeometryUserType

I'm using Hibernate Spatial version 4.0-M1. I'm following the tutorial here. However, my code fails with the following error: org.hibernate.MappingException: Could not determine type for: org.hibernatespatial.GeometryUserType, at #table_name# for column #geometry_column#.
My session factory creation class is as shown below:
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
} catch (Exception ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
After digging around for a possible cause, I've found out that it has something to do with my configuration. My hibernate.cfg.xml is as shown below:
<session-factory>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/dbName</property>
<property name="connection.username">dbUsername</property>
<property name="connection.password">dbPassword</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernatespatial.postgis.PostgisDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
<property name="show_sql">true</property>
<mapping class="com.testapp.model.EntityClassWithAnnotations" />
</session-factory>
Any idea on what I may be doing wrong will be appreciated very much.
UPDATE: My entity class is shown below:
#Entity
#Table(name = "table_name")
public class MyEntityClass implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name = "gid")
private Long gid;
#Column(name = "adm1_name")
private String adminName;
#Column(name = "adm1_code")
private String adminCode;
#Column(name = "pmal")
private Double pmale;
#Column(name = "pfem")
private Double pfemale;
#Type(type = "org.hibernatespatial.GeometryUserType")
#Column(name = "the_geom", nullable = true)
private Geometry geom;
public MyEntityClass() {}
public Long getGid() {
return gid;
}
public void setGid(Long gid) {
this.gid = gid;
}
public String getAdminName() {
return adminName;
}
public void setAdmin_name(String adminName) {
this.adminName = adminName;
}
public String getAdminCode() {
return adminCode;
}
public void setAdmin_code(String adminCode) {
this.adminCode = adminCode;
}
public Double getPmale() {
return pmale;
}
public void setPmale(Double pmale) {
this.pmale = pmale;
}
public Double getPfemale() {
return pfemale;
}
public void setPfemale(Double pfemale) {
this.pfemale = pfemale;
}
public Geometry getGeom() {
return geom;
}
public void setGeom(Geometry geom) {
this.geom = geom;
}
}
EDITED: I think I see the error in your hibernate.cfg file, you are using wrong dialect.
replace your dialect row with:
<property name="hibernate.dialect" value="org.hibernate.spatial.dialect.postgis.PostgisDialect"/>
In my case the hibernate-spatial.jar was missing which includes org.hibernatespatial.GeometryUserType.
We're using maven and the old 1.1.1 version of hibernate spatial so after I added the following to the pom, all was well:
<dependency>
<groupId>org.hibernatespatial</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>1.1.1</version>
</dependency>

Categories