在添加新国家时,我在JSF + Hibernate应用程序中获得会话关闭异常。这是供您参考的代码
country.xhtml
<f:metadata>
<f:event listener="#{country.getPreRequisites}" type="preRenderView"/>
</f:metadata>
上面的代码填充了下面要使用的国家地图。如果我删除f:元数据块,那么我可以添加国家,不会得到会话关闭消息。
<p:selectOneRadio value="#{country.countryId}" id="countryId" columns="4" style="width: 700px" layout="grid">
<f:selectItems value="#{country.countries}" />
</p:selectOneRadio>
CountryManagedBean.java
@ManagedBean(name = "country")
@ViewScoped
public class CountryManagedBean
{
public String saveCountry()
{
String actionFlag="country";
FacesMessage message=null;
try
{
int flag=countryDao.saveCountry(this);
if(flag==1)
{
message=new FacesMessage(FacesMessage.SEVERITY_INFO,"Country","Saved Successfully");
FacesContext.getCurrentInstance().addMessage(null, message);
}
}
catch(Exception e)
{
LOG.logp(Level.SEVERE, "CountryManagedBean","saveCountry", "Saving Country Failed", e);
}
return actionFlag;
}
public void getPreRequisites(ComponentSystemEvent event)
{
FacesContext fc = FacesContext.getCurrentInstance();
if (!fc.isPostback()) //Page Is Called / Rendered
{
countryDao.getPreRequisites(this);
}
}
}
CountryDao.java
public class CountryDao
{
Session session = null;
Transaction tx=null;
public void getPreRequisites(CountryManagedBean country)
{
try
{
tx=session.beginTransaction();
Criteria cr=session.createCriteria(CountryPojo.class)
.setProjection(Projections.projectionList()
.add(Projections.property("countryId"),"countryId")
.add(Projections.property("countryName"),"countryName")
.add(Projections.property("countryShortCode"),"countryShortCode")
)
.setResultTransformer(Transformers.aliasToBean(CountryPojo.class));
List<CountryPojo> countryList=cr.list();
System.out.println("Total Countries Found:"+countryList.size());
for(CountryPojo pojo:countryList)
{
country.getCountries().put(pojo.getCountryName()+" ["+pojo.getCountryShortCode()+"]",pojo.getCountryId());
}
CountryPojo p=countryList.get(0);
System.out.println("%%%%%%%%%%% Country Id:"+p.getCountryId()+"t############# Country Name:"+p.getCountryName());
tx.commit();
}
catch(HibernateException e)
{
LOG.logp(Level.SEVERE, "Country Dao", "getPreRequisites","Caught HibernateException while getting pre requisites",e);
try
{
tx.rollback();
}
catch(HibernateException ex)
{
LOG.logp(Level.SEVERE,"CountryDao","getPreRequisites","Caught HibernateException while rolling back transaction",ex);
}
}
finally
{
}
}
public int saveCountry(CountryManagedBean country)
{
int flag=-1;
try
{
tx=session.beginTransaction();
CountryPojo countryPojo=new CountryPojo(country.getCountryName(),country.getCountryShortCode(),country.getLastUpdateBy());
country.setCountryId((Integer)session.save(countryPojo));
LOG.log(Level.INFO, "Country {0} Saved With Id {1}", new Object[]{country.getCountryName(), country.getCountryId()});
tx.commit();
}
catch(HibernateException e)
{
LOG.logp(Level.SEVERE, "Country Dao", "saveCountry","Caught HibernateException while saving country",e);
try
{
tx.rollback();
}
catch(HibernateException ex)
{
LOG.logp(Level.SEVERE,"CountryDao","saveCountry","Caught HibernateException while rolling back transaction",ex);
}
}
finally
{
}
return flag;
}
public CountryDao()
{
session = HibernateUtil.getSessionFactory().getCurrentSession();
}
private static final Logger LOG = Logger.getLogger(CountryDao.class.getName());
}
很可能是因为JSF调用getPreRequisites
时关闭了JPA/Hibernate会话。你需要将这个添加到你的web.xml中,以保持会话打开,以便视图可以加载你的延迟加载对象。
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>