I have a serious problem retrieving records from a database.
Using the jsp code below.
The customer object has a subobject account.
Both have Id fields autogenerated.
The ID field of customer is 0 and contains a valid customer.
The ID field of account is 1 and contains a valid account.
The ID of customer is passed to this page using a get-parameter value.
When the query is run using an customer id of 1 (doesnt exist) the following SQL code is generated and executed:
Code:
DEBUG: Geen SessionFactory Aanwezig
DEBUG: Bezig sessie te openen
DEBUG - opened session at timestamp: 4657447713533952
DEBUG - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG - opening JDBC connection
DEBUG - total checked-out connections: 0
DEBUG - using pooled JDBC connection, pool size: 0
DEBUG - select this_.ID as ID6_2_, this_.HOME_CONTACTADDRESS as HOME2_6_2_, this_.BILL_CONTACTADDRESS as BILL3_6_2_, this_.SHIP_CONTACTADDRESS as SHIP4_6_2_, this_.FIRST_NAME as FIRST5_6_2_, this_.LAST_NAME as LAST6_6_2_, this_.MIDDLE_NAME as MIDDLE7_6_2_, this_.GENDER as GENDER6_2_, this_.DATE_OF_BIRTH as DATE9_6_2_, this_.CUSTOMERSTATE as CUSTOME10_6_2_, this_.ADDITIONDATE as ADDITIO11_6_2_, this_.REVISION as REVISION6_2_, this_.ROOTREVISION as ROOTREV13_6_2_, this_.ACCOUNTID as ACCOUNTID6_2_, account2_.ID as ID11_0_, account2_.USERNAME as USERNAME11_0_, account2_.ADDITIONDATE as ADDITION3_11_0_, account2_.ACCOUNTSTATE as ACCOUNTS4_11_0_, account2_.USERPASS as USERPASS11_0_, account2_.LEVELID as LEVELID11_0_, levels3_.ID as ID9_1_, levels3_.LEVELNAME as LEVELNAME9_1_, levels3_.LEVELSTATE as LEVELSTATE9_1_ from CUSTOMER this_ left outer join ACCOUNT account2_ on this_.ACCOUNTID=account2_.ID left outer join LEVELS levels3_ on account2_.LEVELID=levels3_.ID where this_.ID=?
Hibernate: select this_.ID as ID6_2_, this_.HOME_CONTACTADDRESS as HOME2_6_2_, this_.BILL_CONTACTADDRESS as BILL3_6_2_, this_.SHIP_CONTACTADDRESS as SHIP4_6_2_, this_.FIRST_NAME as FIRST5_6_2_, this_.LAST_NAME as LAST6_6_2_, this_.MIDDLE_NAME as MIDDLE7_6_2_, this_.GENDER as GENDER6_2_, this_.DATE_OF_BIRTH as DATE9_6_2_, this_.CUSTOMERSTATE as CUSTOME10_6_2_, this_.ADDITIONDATE as ADDITIO11_6_2_, this_.REVISION as REVISION6_2_, this_.ROOTREVISION as ROOTREV13_6_2_, this_.ACCOUNTID as ACCOUNTID6_2_, account2_.ID as ID11_0_, account2_.USERNAME as USERNAME11_0_, account2_.ADDITIONDATE as ADDITION3_11_0_, account2_.ACCOUNTSTATE as ACCOUNTS4_11_0_, account2_.USERPASS as USERPASS11_0_, account2_.LEVELID as LEVELID11_0_, levels3_.ID as ID9_1_, levels3_.LEVELNAME as LEVELNAME9_1_, levels3_.LEVELSTATE as LEVELSTATE9_1_ from CUSTOMER this_ left outer join ACCOUNT account2_ on this_.ACCOUNTID=account2_.ID left outer join LEVELS levels3_ on account2_.LEVELID=levels3_.ID where this_.ID=?
DEBUG - preparing statement
DEBUG - binding '1' to parameter: 1
DEBUG - about to open ResultSet (open ResultSets: 0, globally: 0)
DEBUG - processing result set
DEBUG - done processing result set (0 rows)
DEBUG - about to close ResultSet (open ResultSets: 1, globally: 1)
DEBUG - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG - closing statement
DEBUG - total objects hydrated: 0
DEBUG - initializing non-lazy collections
DEBUG - after autocommit
DEBUG - aggressively releasing JDBC connection
DEBUG - closing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
DEBUG - returning connection to pool, pool size: 1
DEBUG: FLAG #6
DEBUG - closing session
DEBUG - connection already null in cleanup : no action
This is correct because there is no customer with id = 1
If I rerun it with id = 0 (which DOES exist in the database) i get:
Code:
2006-01-12 14:27:23 StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
java.lang.OutOfMemoryError: Java heap space
So everthing is ok as long as it doesn't return any records.
Moreover, when I execute:
Code:
Criteria query = hibernateSession.createCriteria(Customer.class);
customers = query.list().iterator();
or
c = (Customer) hibernateSession.get(Customer.class,new Integer(0));
there is no problem and i can for example use <%=c.getFirstName()%> with success.
Can someone address to me what I am doing wrong?
Below is the full information block.
Hibernate version: Hibernate-Version: 3.1.
Mapping documents:ACCOUNT:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.2
http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->
<class
name="shogun.hibernate.Account"
table="ACCOUNT"
lazy="false"
>
<id
name="id"
type="java.lang.Integer"
column="ID"
>
<generator class="sequence">
<param name="sequence">G_ACCOUNT_ID</param>
</generator>
</id>
<property
name="username"
type="java.lang.String"
column="USERNAME"
not-null="true"
length="765"
/>
<property
name="additiondate"
type="java.sql.Timestamp"
column="ADDITIONDATE"
not-null="true"
length="19"
/>
<property
name="accountstate"
type="short"
column="ACCOUNTSTATE"
not-null="true"
length="5"
/>
<property
name="userpass"
type="java.lang.String"
column="USERPASS"
not-null="true"
length="765"
/>
<!-- Associations -->
<!-- bi-directional one-to-many association to Customer -->
<set
name="customers"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="ACCOUNTID" />
</key>
<one-to-many
class="shogun.hibernate.Customer"
/>
</set>
<!-- bi-directional many-to-one association to Levels -->
<many-to-one
name="level"
class="shogun.hibernate.Levels"
not-null="true"
>
<column name="LEVELID" />
</many-to-one>
</class>
</hibernate-mapping>
CUSTOMER
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<!--
Created by the Middlegen Hibernate plugin 2.2
http://boss.bekk.no/boss/middlegen/
http://www.hibernate.org/
-->
<class
name="shogun.hibernate.Customer"
table="CUSTOMER"
lazy="false"
>
<id
name="id"
type="java.lang.Integer"
column="ID"
>
<generator class="sequence">
<param name="sequence">G_CUSTOMER_ID</param>
</generator>
</id>
<property
name="homeContactaddress"
type="java.lang.Short"
column="HOME_CONTACTADDRESS"
length="5"
/>
<property
name="billContactaddress"
type="java.lang.Short"
column="BILL_CONTACTADDRESS"
length="5"
/>
<property
name="shipContactaddress"
type="java.lang.Short"
column="SHIP_CONTACTADDRESS"
length="5"
/>
<property
name="firstName"
type="java.lang.String"
column="FIRST_NAME"
not-null="true"
length="765"
/>
<property
name="lastName"
type="java.lang.String"
column="LAST_NAME"
not-null="true"
length="765"
/>
<property
name="middleName"
type="java.lang.String"
column="MIDDLE_NAME"
length="765"
/>
<property
name="gender"
type="short"
column="GENDER"
not-null="true"
length="5"
/>
<property
name="dateOfBirth"
type="java.sql.Date"
column="DATE_OF_BIRTH"
not-null="true"
length="10"
/>
<property
name="customerstate"
type="short"
column="CUSTOMERSTATE"
not-null="true"
length="5"
/>
<property
name="additiondate"
type="java.sql.Timestamp"
column="ADDITIONDATE"
not-null="true"
length="19"
/>
<property
name="revision"
type="int"
column="REVISION"
not-null="true"
length="10"
/>
<property
name="rootrevision"
type="int"
column="ROOTREVISION"
not-null="true"
length="10"
/>
<!-- Associations -->
<!-- bi-directional many-to-one association to Account -->
<many-to-one
name="account"
class="shogun.hibernate.Account"
not-null="true"
>
<column name="ACCOUNTID" />
</many-to-one>
<!-- bi-directional one-to-many association to Order -->
<set
name="orders"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="CUSTOMERID" />
</key>
<one-to-many
class="shogun.hibernate.Order"
/>
</set>
<!-- bi-directional one-to-many association to Paymentdata -->
<set
name="paymentdatas"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="CUSTOMERID" />
</key>
<one-to-many
class="shogun.hibernate.Paymentdata"
/>
</set>
<!-- bi-directional one-to-many association to Cart -->
<set
name="carts"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="CUSTOMERID" />
</key>
<one-to-many
class="shogun.hibernate.Cart"
/>
</set>
<!-- bi-directional one-to-many association to Contactdata -->
<set
name="contactdatas"
lazy="true"
inverse="true"
cascade="all"
>
<key>
<column name="CUSTOMERID" />
</key>
<one-to-many
class="shogun.hibernate.Contactdata"
/>
</set>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
<%
Customer customer = null;
java.util.List customers = null;
if (request.getParameter("id") != null) {
System.out.println("-[editcustomer]------------------------------------------------------");
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
String error = "";
Session hibernateSession = null;
try{
//Verkrijg een sessie
hibernateSession = AppSession.getSession();
Criteria crit = hibernateSession.createCriteria(Customer.class);
crit.add(Expression.eq("account.id", Integer.parseInt(request.getParameter("id"))));
customers = crit.list();
System.out.println("DEBUG: FLAG #6");
} catch (Exception e) {
error = e.getMessage(); e.printStackTrace();
}
finally {
try { hibernateSession.close();}
catch (Exception e){;}
}
} %>
<% if (customers!= null && customers.size() > 0){
System.out.println("DEBUG: FLAG #1");
while (customers.iterator().hasNext()) {
Customer myCustomer = (Customer)customers.iterator().next();
System.out.println("Result:"+myCustomer.getFirstName());
}
System.out.println("DEBUG: FLAG #2");
//customer = (Customer)customers.get(0);
System.out.println("DEBUG: FLAG #3");
%>
Full stack trace of any exception that occurs:
2006-01-12 13:58:16 StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
java.lang.OutOfMemoryError: Java heap space
Name and version of the database you are using:
FireBird (latest)
The generated SQL (show_sql=true):
None due to the exception
Debug level Hibernate log excerpt:
Same.