I am programming what I intend to be a readonly web application. I have a List variable that I use to store the results of a query and then assign to a List property of a persistent object (this property is not managed by Hibernate). The first assignment works ok, the second causes hibernate to try to update the first record in the List which is unwanted so I changed the mappings to readonly (see below). I cannot retrieve the "DocumentControl" for any "DiscrepancyReport" item passed the first.
Also, due to poor schema design and a non-exact parent-child relationship, I cannot use Hibernate collections mapping (I am essentially trying to manually load collections).
Please let me know if I am doing anything wrong here, thanks.
Hibernate version:2.1.4
Mapping documents:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="aero.mycompany.schema.DiscrepancyReport" table="DISCREPANCY_REPORT" schema="ODB">
<cache usage="read-only"/>
<id name="discrepancyNo" column="DISCREPANCY_NO" type="java.lang.Integer">
<generator class="native"/>
</id>
<property name="status" column="STATUS" type="java.lang.String" length="11"/>
<property name="module" column="MODULE" type="java.lang.String" length="20"/>
<property name="program" column="PROGRAM" type="java.lang.String" length="45"/>
<property name="discrepancyDescription" column="DISCREPANCY_DESCRIPTION" type="java.lang.String" length="2000"/>
<property name="createdDate" column="CREATED_DATE" type="java.util.Date" length="7"/>
<property name="priority" column="PRIORITY" type="java.lang.String" length="10"/>
<property name="customer" column="CUSTOMER" type="java.lang.String" length="30"/>
<property name="resolution" column="RESOLUTION" type="java.lang.String" length="2000"/>
<property name="releaseNo" column="RELEASE_NO" type="java.lang.String" length="30"/>
<property name="documentNo" column="DOCUMENT_NO" type="java.lang.Integer" length="8"/>
</class>
</hibernate-mapping>
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="aero.mycompany.schema.DocumentControl" table="DOCUMENT_CONTROL" schema="ODB">
<cache usage="read-only"/>
<composite-id>
<key-property name="documentNo" column="DOCUMENT_NO" type="java.lang.Integer" length="8"></key-property>
<key-property name="item" column="ITEM" type="java.lang.Integer" length="5"/>
</composite-id>
<property name="path" column="PATH" type="java.lang.String" length="500"/>
<property name="document" column="DOCUMENT" type="java.lang.String" length="120"/>
<property name="documentType" column="DOCUMENT_TYPE" type="java.lang.String" length="20"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():in class
HibLogReportServiceCode:
List results = null;
try{
Session session = HibernateSessionFactory.getSession();
String comp, customer;
Criteria crit = null;
crit = session.createCriteria(DiscrepancyReport.class);
//some of this
/* if (...) then crit.add(...); */
results = crit.list();
Hibernate.initialize(results);
Iterator iter = results.iterator();
DiscrepancyReport dr = null;
while(iter.hasNext()){
dr = (DiscrepancyReport)iter.next();
Integer docno = dr.getDocumentNo();
if(docno != null && docno.compareTo(Integer.valueOf("0")) > 0){
dr.setDocumentControlList(
session.createCriteria(DocumentControl.class)
.add(Expression.eq("documentNo", docno))
.list())
}
}catch(...){}
finally{
}
Full stack trace of any exception that occurs:
java.lang.UnsupportedOperationException: Can't write to a readonly object
at net.sf.hibernate.cache.ReadOnlyCache.lock(ReadOnlyCache.java:36)
at net.sf.hibernate.impl.ScheduledUpdate.execute(ScheduledUpdate.java:50)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2407)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2361)
at net.sf.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1800)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:3596)
at net.sf.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:238)
at aero.mycompany.logreport.service.HibLogReportService.getLogReportList(HibLogReportService.java:301)
at aero.mycompany.struts.logreport.actions.LogReportAction.executeAction(LogReportAction.java:38)
at aero.mycompany.struts.logreport.actions.LogReportBaseAction.execute(LogReportBaseAction.java:34)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.authenticator.SingleSignOn.invoke(SingleSignOn.java:444)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:793)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:702)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:571)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:644)
at java.lang.Thread.run(Thread.java:536)
Name and version of the database you are using:
Oracle 9i
The generated SQL (show_sql=true):
Hibernate: select this.DOCUMENT_NO as DOCUMENT1_0_, this.ITEM as ITEM0_, this.PATH as PATH0_, this.DOCUMENT as DOCUMENT0_, this.DOCUMENT_TYPE as DOCUMENT5_0_ from ODB.DOCUMENT_CONTROL this where this.DOCUMENT_NO=?
Debug level Hibernate log excerpt:
33297 14:05:37,531 ERROR net.sf.hibernate.cache.ReadOnlyCache - Application attempted to edit read only item: aero.mycompany.schema.DocumentControl@28bda[documentNo=15288,item=1]