SITUATION:
I have a <class> Holder which contains a <component> class Container1 which, in turn, has a List of objects of <class> Container2.
---
CLASS DEFINITIONS:
This is Holder:
Code:
package testPZ;
import java.io.Serializable;
public class Holder implements Serializable{
private static final long serialVersionUID = 1L;
String oid;
Container1 con1;
public Holder(){
}
public Holder(String _oid){
oid = _oid;
}
public Container1 getCon1() {
return con1;
}
public void setCon1(Container1 con1) {
this.con1 = con1;
}
public String getOid() {
return oid;
}
public void setOid(String oid) {
this.oid = oid;
}
}
This is Container1:
Code:
package testPZ;
import java.io.Serializable;
import java.util.*;
public class Container1 implements Serializable{
private static final long serialVersionUID = 1L;
int a;
List listCon2 = new ArrayList();
public Container1(){
}
public Container1(int _a){
a = _a;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public List getListCon2() {
return listCon2;
}
public void setListCon2(List listCon2) {
this.listCon2 = listCon2;
}
}
And this is Container2:
Code:
package testPZ;
import java.io.Serializable;
public class Container2 implements Serializable{
private static final long serialVersionUID = 1L;
String oid;
public Container2(){
}
public Container2(String _oid){
oid = _oid;
}
public String getOid() {
return oid;
}
public void setOid(String oid) {
this.oid = oid;
}
}
---
XML FILES:
This is the hibernate.cfg.xml:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<property name="connection.url">
jdbc:hsqldb:hsql://localhost/training
</property>
<property name="connection.driver_class">
org.hsqldb.jdbcDriver
</property>
<property name="dialect">
org.hibernate.dialect.HSQLDialect
</property>
<property name="hibernate.jdbc.batch_size">
0
</property>
<property name="hibernate.cglib.use_reflection_optimizer">
false;
</property>
</session-factory>
</hibernate-configuration>
As you can see, Holder is mapped with a <class> tag, Container1 as a <component> which in turn contains a <list> of <class> Container2. Here is the complete XML file mapping.xml:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping auto-import="false" default-cascade="none">
<!--table="Holder"-->
<class name="testPZ.Holder" table="Holder">
<cache usage="read-write"/>
<composite-id>
<key-property name="oid" type="string">
<column name="oid" sql-type="char(35)"/>
</key-property>
</composite-id>
<component name="con1">
<property name="a" type="int">
<!--column name="a"-->
<column name="container1_a" default="0" length="512"/>
</property>
<list lazy="false" fetch="subselect" name="listCon2">
<cache usage="read-write"/>
<key>
<!--column name=""/-->
<column name="fk_holder" index="i_con2" sql-type="char(35)"/>
</key>
<!--index column="si_accountHolders_accountData"/-->
<index column="si_con2"/>
<one-to-many class="testPZ.Container2"/>
</list>
</component>
</class>
<!--table="TAccountHolder"-->
<class name="testPZ.Container2" table="Container2">
<cache usage="read-write"/>
<id name="oid" type="string">
<column name="oid" sql-type="char(35)"/>
</id>
</class>
</hibernate-mapping>
---
TESTS:
First of all I create the db schema with the following code snippet:
Code:
Configuration cfg = new Configuration();
cfg.configure();
cfg.addFile("test/mapping.xml");
SchemaExport se = new SchemaExport(cfg);
se.create(false, true);
Then I save an object Holder with its child and grandchildren:
Code:
Configuration cfg = new Configuration();
cfg.configure();
cfg.addFile("test/mapping.xml");
Holder h = new Holder("1");
h.con1 = new Container1(2);
Container2 con2_1 = new Container2("2");
h.con1.listCon2.add(con2_1);
sf = cfg.buildSessionFactory();
s = sf.openSession();
Transaction t = s.beginTransaction();
s.saveOrUpdate(con2_1);
s.saveOrUpdate(h);
t.commit();
s.close();
The db is set properly, with one row for the instance of the Holder class and one row for the instance of the Container2 class, with fk properly set to point to Holder's pk.
So, I try to load back objects from table Holder with this query:
Code:
Configuration cfg = new Configuration();
cfg.configure();
cfg.addFile("test/mapping.xml");
sf = cfg.buildSessionFactory();
s = sf.openSession();
Query q = s.createQuery("select h.con1 from testPZ.Holder h");
List l = q.list();
System.out.println(((Container1) l.iterator().next()).getListCon2());
I expected it to be properly set to the object retrieved from Container2 table but the outcome is null.
---
FULL LOG:
Code:
- Hibernate 3.1
- hibernate.properties not found
- using CGLIB reflection optimizer
- using JDK 1.4 java.sql.Timestamp handling
- configuring from resource: /hibernate.cfg.xml
- Configuration resource: /hibernate.cfg.xml
- Configured SessionFactory: null
- Reading mappings from file: test/testPZ/mapping.xml
- Mapping class: testPZ.Holder -> Holder
- Mapping class: testPZ.Container2 -> Container2
- processing extends queue
- processing collection mappings
- Mapping collection: testPZ.Holder.con1.listCon2 -> Container2
- processing association property references
- processing foreign key constraints
- composite-id class does not override equals(): testPZ.Holder
- composite-id class does not override hashCode(): testPZ.Holder
- Using Hibernate built-in connection pool (not for production use!)
- Hibernate connection pool size: 20
- autocommit mode: false
- using driver: org.hsqldb.jdbcDriver at URL: jdbc:hsqldb:hsql://localhost/training
- connection properties: {user=sa, password=****}
- RDBMS: HSQL Database Engine, version: 1.8.0
- JDBC driver: HSQL Database Engine Driver, version: 1.8.0
- Using dialect: org.hibernate.dialect.HSQLDialect
- Using default transaction strategy (direct JDBC transactions)
- No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
- Automatic flush during beforeCompletion(): disabled
- Automatic session close at end of transaction: disabled
- Scrollable result sets: enabled
- JDBC3 getGeneratedKeys(): disabled
- Connection release mode: auto
- Default batch fetch size: 1
- Generate SQL with comments: disabled
- Order SQL updates by primary key: disabled
- Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
- Using ASTQueryTranslatorFactory
- Query language substitutions: {}
- Second-level cache: enabled
- Query cache: disabled
- Cache provider: org.hibernate.cache.EhCacheProvider
- Optimize cache for minimal puts: disabled
- Structured second-level cache entries: disabled
- Statistics: disabled
- Deleted entity synthetic identifier rollback: disabled
- Default entity-mode: pojo
- building session factory
- Could not find configuration [testPZ.Container2]; using defaults.
- Could not find configuration [testPZ.Holder]; using defaults.
- Could not find configuration [testPZ.Holder.con1.listCon2]; using defaults.
- Not binding factory to JNDI, no JNDI name configured
- Checking 0 named HQL queries
- Checking 0 named SQL queries
null