My application faces numerous LazyExceptions issues and what causes a "filth" in the server log. I understand that they occur because the connection to the database has already been closed and I am trying to recover some attribute / object that has not been initialized.
The most recent problem I had was getting a LazyException in the filter because the ProductValue merchants were not initialized. These occur only in a specific system flow.
Service
List<ProdutoValorETO> valores = mgrProdutoValorEDAO.findByProdutoId(produto.getId());
Optional<ProdutoValorETO> optionalProdValor = valores.stream()
.filter(v -> v.getLojista().getId().equals(lojista.getId()))
.findFirst();
DAO
public List<ProdutoValorETO> findByProdutoId(Long id) {
if (id != null) {
String query =
" SELECT * " +
" FROM produtovalor " +
" WHERE idproduto = " + id + " AND ativo = TRUE; ";
SQLQuery eQuery = getCurrentSession().createSQLQuery(query).addEntity(ProdutoValorETO.class);
List<ProdutoValorETO> lista = CastUtils.castList(eQuery.list(), ProdutoValorETO.class);
}
return new ArrayList<>();
}
I solved it as follows but it seems more like a workaround:
public List<ProdutoValorETO> findByProdutoId(Long id) {
if (id != null) {
String query =
" SELECT * " +
" FROM produtovalor " +
" WHERE idproduto = " + id + " AND ativo = TRUE; ";
SQLQuery eQuery = getCurrentSession().createSQLQuery(query).addEntity(ProdutoValorETO.class);
List<ProdutoValorETO> lista = CastUtils.castList(eQuery.list(), ProdutoValorETO.class);
for (ProdutoValorETO item : lista) {
Hibernate.initialize(item);
}
}
return new ArrayList<>();
}
Setup
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="poolName" value="springHikariCP" />
<property name="dataSourceClassName" value="org.postgresql.ds.PGSimpleDataSource" />
<property name="leakDetectionThreshold" value="30000"/>
<property name="connectionTimeout" value="30000" />
<property name="idleTimeout" value="600000"/>
<property name="maxLifetime" value="1800000"/>
<property name="maximumPoolSize" value="5"/>
<property name="registerMbeans" value="true"/>
<!-- <property name="jdbcUrl" value="${jdbc.url}"/> -->
<property name="connectionTestQuery" value="select 1"/>
<property name="dataSourceProperties">
<props>
<prop key="url">${jdbc.url}</prop>
<prop key="user">${jdbc.username}</prop>
<prop key="password">${jdbc.password}</prop>
</props>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="br.com.example.*.to"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
ProductValorETO
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "idProduto")
private ProdutoETO produto;
Product
@OneToMany(mappedBy = "produto", targetEntity = ProdutoValorETO.class, cascade = {CascadeType.ALL}, fetch = FetchType.LAZY)
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private List<ProdutoValorETO> valores;