Ленивая инициализация с помощью JPA Spring Hibernate JSF 2.0
У меня проблема с моим веб-проектом ... Проблема связана с LazyInitialization ...
Я покажу вам ошибку:
failed to lazily initialize a collection of role: com.catalogor3e.entity.Camada.fornecedores, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.catalogor3e.entity.Camada.fornecedores, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(Abst ractPersistentCollection.java:358)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:97)
at org.hibernate.collection.PersistentBag.size(PersistentBag.java:225)
at javax.faces.model.ListDataModel.isRowAvailable(ListDataModel.java:110)
at javax.faces.model.ListDataModel.setRowIndex(ListDataModel.java:185)
at javax.faces.model.ListDataModel.setWrappedData(ListDataModel.java:220)
at javax.faces.model.ListDataModel.<init>(ListDataModel.java:79)
at javax.faces.component.UIData.getDataModel(UIData.java:1804)
at javax.faces.component.UIData.setRowIndexWithoutRowStatePreserved(UIData.java:484)
at javax.faces.component.UIData.setRowIndex(UIData.java:473)
at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:81)
at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:820)
at javax.faces.component.UIData.encodeBegin(UIData.java:1118)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:52)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:57)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:57)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:57)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:57)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:57)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.layout.LayoutUnitRenderer.encodeEnd(LayoutUnitRenderer.java:51)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1764)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1760)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewConte xtImpl.java:518)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at javax.faces.component.UIForm.visitTree(UIForm.java:354)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:297)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:981)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1757)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:409)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Abr 18, 2013 9:21:20 AM com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback visit
SEVERE: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.catalogor3e.entity.Camada.fornecedores, no session or session was closed
Теперь я покажу вам некоторые используемые классы:
Вот класс Камада:
@javax.persistence.Entity
@Table(name="camada")
public class Camada extends Entity{
@Id
@Column(name="id", nullable=false)
@GeneratedValue(strategy= GenerationType.AUTO)
private Integer id;
@Column(name="nome_material", nullable=false)
private String nome;
@Column(name="espessura")
private Double espessura;
@Column(name="espessura_fixa", nullable=false)
private Double espessuraFixa;
@Column(name="condutividade")
private Double condutividade;
@Column(name="calor_especifico")
private Double calorEspecifico;
@Column(name="densidade_minima")
private Double densidadeMinima;
@Column(name="densidade_maxima")
private Double densidadeMaxima;
@Column(name="fonte")
private String fonte;
@ManyToOne
@JoinColumn(name="id_categoria")
private CategoriaCamada categoria;
@ManyToMany(targetEntity=Sistema.class, mappedBy="camadas")
@JoinTable(name="sistema_camada")
private List<Sistema> sistemas;
@ManyToOne
@JoinColumn(name="id_fabricante")
private Fabricante fabricante;
@ManyToMany(targetEntity=Fornecedor.class)
@JoinTable(name="camada_fornecedor", joinColumns=@JoinColumn(name="id_camada"), inverseJoinColumns=@JoinColumn(name="id_fornecedor"))
private List<Fornecedor> fornecedores;
@Column(name="descricao")
private String descricao;
@Lob
@Basic(fetch= FetchType.LAZY)
private byte[] imagem;
public Camada() {
}
public StreamedContent mostrarImagemDeByte(){
InputStream in = null;
StreamedContent sc;
if(this.imagem != null){
in = new ByteArrayInputStream(this.imagem);
}
if( in != null){
sc = new DefaultStreamedContent(in);
}else{
sc = null;
}
return sc;
}
Вот класс Fornecedor:
@javax.persistence.Entity
@Table(name="fornecedor")
public class Fornecedor extends Entity{
@Id
@Column(name="id", nullable=false)
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Integer id;
@Column(name="nome", nullable=false)
private String nome;
@Column(name="telefone")
private String telefone;
@Column(name="email")
private String email;
@Column(name="website")
private String website;
@ManyToMany(targetEntity=Fabricante.class, mappedBy="fornecedores")
@JoinTable(name="fabricante_fornecedor")
public List<Fabricante> fabricantes;
@ManyToMany(targetEntity=Sistema.class, mappedBy="fornecedores")
@JoinTable(name="sistema_fornecedor")
public List<Sistema> sistemas;
@ManyToMany(targetEntity=Camada.class, mappedBy="fornecedores")
@JoinTable(name="camada_fornecedor")
public List<Camada> camadas;
public Fornecedor() {
}
Вот мой web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter>
<filter-name>
OpenEntityManagerInViewFilter
</filter-name>
<filter-class>
org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
</filter>
<!-- Include this if you are using Hibernate -->
<filter-mapping>
<filter-name>OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>bootstrap</param-value>
</context-param>
</web-app>
А вот и мое приложениеContext.xml
<?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/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">
<!-- Seta anotaçoes para serem <context:annotation-config />usadas pelo Spring -->
<context:annotation-config />
<!-- Define o pacote onde o Spring vai procurar por beans anotados -->
<context:component-scan base-package="com.catalogor3e.dao, com.catalogor3e.service" />
<!-- define que as transaçoes irao ser anotadas -->
<tx:annotation-driven />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/bancodedados"/>
<property name="username" value="root"/>
<property name="password" value="852456"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="catalogoPU" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<!-- Configuracao do gerente de transacoes do Spring -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
вот класс DAO для доступа:
@Repository("sistemasDAO")
@Transactional
public class SistemasDAO{
@PersistenceContext
private EntityManager entityManager;
public SistemasDAO() {
}
public List<Sistema> getTodosOsSistemas(){
Query query = entityManager.createQuery("select sistemas from Sistema sistemas");
List<Sistema> sistemas = query.getResultList();
return sistemas;
}
public List<Sistema> filtrarSistemaConstrutivo(CategoriaSistema categoriaDoSistema, List<CategoriaCamada> categoriasDeCamada, Fabricante fabricante, ZonaBioclimatica zona, Etiqueta etiqueta){
List<Sistema> listaDeSistemasFiltrados = new ArrayList<Sistema>();
Query query;
String qr = "SELECT DISTINCT sistema FROM Sistema sistema, IN(sistema.relacionamentoZonaEtiquetaSistema) relacionamento ";
if(categoriaDoSistema != null){ //se foi selecionado um tipo de sistema para filtro
qr = qr + " WHERE sistema.categoria.id = ";
qr = qr + categoriaDoSistema.getId();
}
if(fabricante != null && categoriaDoSistema != null){ //foi escolhido categoria de Sistema e fabricante para filtro
qr = qr + " AND sistema.fabricante.id = ";
qr = qr + fabricante.getId();
}else if(fabricante != null && categoriaDoSistema == null){//foi escolhi fabricante mas não foi escolhido categoriaDoSistema
qr = qr + " WHERE sistema.fabricante.id = ";
qr = qr + fabricante.getId();
}
if(zona != null && etiqueta != null){//só entra nesse filtro se os dois tiverem sido selecionados
if(categoriaDoSistema != null || fabricante != null){ // significa que foi selecionado ou uma categoria de sistema ou um fabricante para filtro
qr = qr + " AND relacionamento.etiqueta.id = ";
qr = qr + etiqueta.getId();
qr = qr + " AND relacionamento.zona.id = ";
qr = qr + zona.getId();
qr = qr + " OR relacionamento is null ";
}else{ //significa que não foi selecionado nem categoria de sistema nem fabricante para filtro, então só filta etiqueta com zona
qr = qr + "WHERE relacionamento.etiqueta.id = ";
qr = qr + etiqueta.getId();
qr = qr + " AND relacionamento.zona.id = ";
qr = qr + zona.getId();
qr = qr + " OR relacionamento is null";
}
}
if(categoriasDeCamada != null && !categoriasDeCamada.isEmpty()){ //se foi escolhido alguma categoria de camada para filtro
if(categoriaDoSistema != null || fabricante != null || zona != null || etiqueta != null){
qr = qr + " AND sistema.id IN ";
List<String> listaDeParenteses = new ArrayList<String>();
for(int i = 0; i < categoriasDeCamada.size(); i++){
if(i < categoriasDeCamada.size() - 1){
qr = qr + " (SELECT sistema FROM Sistema sistema, IN (sistema.camadas) camada WHERE camada.categoria.id = ";
qr = qr + categoriasDeCamada.get(i).getId();
qr = qr + " AND sistema.id IN ";
listaDeParenteses.add(")");
}else{
qr = qr + " (SELECT sistema FROM Sistema sistema, IN (sistema.camadas) camada WHERE camada.categoria.id = ";
qr = qr + categoriasDeCamada.get(i).getId();
listaDeParenteses.add(")");
}
}
for (int i = 0; i<listaDeParenteses.size(); i++){
qr = qr + listaDeParenteses.get(i);
}
}else{
qr = qr + "WHERE sistema.id IN ";
List<String> listaDeParenteses = new ArrayList<String>();
for(int i = 0; i < categoriasDeCamada.size(); i++){
if(i < categoriasDeCamada.size() - 1){
qr = qr + " (SELECT sistema FROM Sistema sistema, IN (sistema.camadas) camada WHERE camada.categoria.id = ";
qr = qr + categoriasDeCamada.get(i).getId();
qr = qr + " AND sistema.id IN ";
listaDeParenteses.add(")");
}else{
qr = qr + " (SELECT sistema FROM Sistema sistema, IN (sistema.camadas) camada WHERE camada.categoria.id = ";
qr = qr + categoriasDeCamada.get(i).getId();
listaDeParenteses.add(")");
}
}
for (int i = 0; i<listaDeParenteses.size(); i++){
qr = qr + listaDeParenteses.get(i);
}
}
}
query = entityManager.createQuery(qr);
listaDeSistemasFiltrados = query.getResultList();
return listaDeSistemasFiltrados;
}
public List<Sistema> testeQuery(){
Query query = entityManager.createQuery("SELECT DISTINCT sis FROM Sistema sis LEFT JOIN FETCH sis.camadas camada WHERE camada.categoria.id = 1 AND sis.id IN (SELECT sistema FROM Sistema sistema , IN(sistema.camadas) camada WHERE camada.categoria.id = 2) AND sis.id IN (SELECT sistema FROM Sistema sistema , IN (sistema.camadas) camada WHERE camada.categoria.id = 1)");
List<Sistema> resultado = query.getResultList();
return resultado;
}
public void addSistema(Sistema sistema){
entityManager.persist(sistema);
}
public void deleteSistema(Sistema sistema){
entityManager.remove(sistema);
}
public Sistema getCamadasDeSistemas(){
List<Camada> camadas = new ArrayList<Camada>();
Query query = entityManager.createQuery("select sis from Sistema sis where sis.id = ?1");
query.setParameter(1, 1);
Sistema sis = (Sistema) query.getSingleResult();
return sis;
}
public void getFabricanteDeSistema(){
Sistema sistema = entityManager.find(Sistema.class, 1);
Fabricante fabricante = sistema.getFabricante();
System.out.println(fabricante.getNome());
}
public void getFornecedoresDeSistema(){
Sistema sistema = entityManager.find(Sistema.class, 1);
List<Fornecedor> fornecedores = sistema.getFornecedores();
for(int i = 0; i < fornecedores.size(); i++){
System.out.println(fornecedores.get(i).getNome());
}
}
public void getSistemasDeFornecedor(){
Fornecedor fornecedor = entityManager.find(Fornecedor.class, 1);
for(Sistema sistema : fornecedor.getSistemas()){
System.out.println(sistema.getNome());
}
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
}
Пожалуйста, может ли кто-нибудь помочь мне с этой проблемой? Если вам нужно больше кода, чтобы показать здесь, просто скажите мне, что я пост!
АТТ
Диего Сабино