3
My application faces numerous Lazyexceptions problems and what causes a "mess" 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 on the filter because the retailers of Productovalor 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>
Productovaloreto
@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;
- When we perform a very large flow in the system, is it more likely that a Lazy will occur? I got the list of values one line above when I tried to access the items and already got the Exception.
- Is there a mechanism in Spring JPA or new versions of Hibernate to better handle this? (This application uses Spring 3 Hibernate 3.2)
- Is there any implication in Lazy occurring when directly writing select instead of using Hibernate criteria?
- There are better ways to solve this case (other than Eager)?
Has a mini pattern designs (breaking another pattern) called Open Session in View. Maybe I can help you.
– igventurelli
Edit your question and place your entities involved in the relationship, please. Also, why your method
findByProdutoId
is returning aList
? He shouldn’t return just one object?– Felipe Marinho
@Felipemarinho Added. A product has a list of values, according to the unit you buy is returned a value, business rules.
– Daniela Morais
@Danielamorais Take a look at the answers they have already given. O
Join Fetch
is probably the best solution to your problem.– Felipe Marinho