Hibernate version:
3.1 and 3.2cr2
Name and version of the database you are using:
Tested on PostgreSQL-7.4 and HSQLDB-2.0 and H2-0.9alpha
Inheritance type:
Tested with "table per subclass" and "table per concrete class"
Hi,
I'm in front of a strange problem.
I have 3 classes : A, B and C.
A has a relation to B, and C extends B.
I only insert 2 instances in the database : one A and one C, linked by the relation between A and B.
When I retrieve my A, and I do a getB, I obtain an object which is an instance of B but not an instance of C.
In a junit test, I have :
Code:
Session session = getSession(false);
Criteria criteria = session.createCriteria(A.class);
A a = (A)criteria.uniqueResult();
B b = a.getB();
assertTrue(b instanceof B);
assertTrue(b instanceof C);
session.close();
When I run the test, the line
"assertTrue(b instanceof C);" fails :(
As I said previously,
I only have 2 instances in my DB, it's impossible that I find a B which is not a C !
I inserted my data as follows :
Code:
Session session = getSession(true);
Transaction tx = session.beginTransaction();
C cmano = new C();
cmano.setTata(66);
cmano.setToto(55);
session.save(cmano);
A amano = new A();
amano.setB(cmano);
session.save(amano);
tx.commit();
session.close();
factory.close(); //When using H2 or HSQL, I need to close the factory
I tested it with hibernate 3.1 and 3.2cr2 but got the same problem...
I also tested it on Postgres 7.4, HSQL 2.0 and H2 0.9alpha and got exactly the same problem.
I reproduced the problem with both "per subclass" and "per concrete class" inheritance types.
I'm probably doing wrong somewhere but the fail keep being very strange...
If any of you have an idea, you would be welcome...
Best regards,
Arno.
--------------------------------------------------------------
I can give some details on my model:
AClassCode:
public class A {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
} //A
MappingCode:
<?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>
<class name="org.codelutin.hibtest.inheritance.A" table="atable">
<id type="string">
<generator class="uuid.hex"/>
</id>
<many-to-one name="b" class="org.codelutin.hibtest.inheritance.B"/>
</class>
</hibernate-mapping>
BClassCode:
public class B {
private int toto;
public int getToto() {
return toto;
}
public void setToto(int toto) {
this.toto = toto;
}
} //B
MappingCode:
<?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>
<class name="org.codelutin.hibtest.inheritance.B" table="btable">
<id type="string">
<generator class="uuid.hex"/>
</id>
<property name="toto" type="int"/>
</class>
</hibernate-mapping>
CClassCode:
public class C extends B {
private int tata;
public int getTata() {
return tata;
}
public void setTata(int tata) {
this.tata = tata;
}
} //C
MappingCode:
<?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>
<union-subclass name="org.codelutin.hibtest.inheritance.C" table="ctable"
extends="org.codelutin.hibtest.inheritance.B">
<property name="tata" type="int"/>
</union-subclass>
</hibernate-mapping>
The test classCode:
import java.util.Properties;
import junit.framework.TestCase;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class InheritanceTestMano extends TestCase {
protected static SessionFactory factory;
protected Properties getConfig(boolean create) {
Properties config = new Properties();
config.setProperty("hibernate.show_sql", "true");
if (create) {
config.setProperty("hibernate.hbm2ddl.auto", "create");
}
config.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
config.setProperty("hibernate.connection.driver_class", "org.h2.Driver");
config.setProperty("hibernate.connection.url", "jdbc:h2:data/hibtest");
config.setProperty("hibernate.connection.username", "sa");
config.setProperty("hibernate.connection.password", "");
return config;
}
protected void createData() throws Exception {
Session session = getSession(true);
Transaction tx = session.beginTransaction();
C cmano = new C();
cmano.setTata(66);
cmano.setToto(55);
session.save(cmano);
A amano = new A();
amano.setB(cmano);
session.save(amano);
tx.commit();
session.close();
factory.close(); //When using H2 or HSQL, I need to close the factory
}
private Session getSession(boolean create) {
if (factory == null) {
Configuration cfg = new Configuration();
cfg.addClass(A.class);
cfg.addClass(B.class);
cfg.addClass(C.class);
cfg.setProperties(getConfig(create));
factory = cfg.buildSessionFactory();
}
return factory.openSession();
}
public void testInheritance() throws Exception {
Session session = getSession(false);
Criteria criteria = session.createCriteria(B.class);
B b = (B)criteria.uniqueResult();
assertTrue(b instanceof B);
assertTrue(b instanceof C);
session.close();
}
public void testInheritanceFromA() throws Exception {
Session session = getSession(false);
Criteria criteria = session.createCriteria(A.class);
A a = (A)criteria.uniqueResult();
B b = a.getB();
assertTrue(b instanceof B);
assertTrue(b instanceof C);
session.close();
}
public static void main(String[] args) throws Exception {
InheritanceTestMano test = new InheritanceTestMano();
test.createData();
}
} //InheritanceTestMano