I'm very confused by the behavior I'm seeing. I must be doing something wrong, but the code I have seems very similar to other examples I've seen in my googling (some from this forum though I neglected to keep around the links).
I'm just trying to represent some simple hierarchical data. This was part of a more complicated system, but I pulled it out and tried to simplify it as much as possible and still can't get it to work, so any help is appreciated.
I've copied and pasted three files. First is my Java class where I'm setting up my mappings using annotations. Second is a simple Spring file where I'm configuring a basic in-memory database using HSQL, setting up the session factory and transaction manger, etc, and third is a JUnit test that is failing.
It is the final assert in the JUnit test that is failing, basically no children are being retrieved, the children list has size 0. The manual query I do to find any nodes with the parent behaves as expected, I get back the single child node.
Ideas?
Oh, and I am using hibernate 3.6.4...
Code:
@Entity
public class Node {
private Long id;
private Node parent;
private List<Node> children = new ArrayList<Node>();
@Id
@GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@ManyToOne
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
@OneToMany(mappedBy="parent")
public List<Node> getChildren() {
return children;
}
public void setChildren(List<Node> children) {
this.children = children;
}
}
Code:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" p:driverClassName="org.hsqldb.jdbcDriver"
p:url="jdbc:hsqldb:mem:test" p:username="sa" p:password=""
p:testOnBorrow="true" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
</props>
</property>
<property name="eventListeners">
<map>
<entry key="merge">
<bean
class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener" />
</entry>
</map>
</property>
<property name="packagesToScan" value="com.entitytest" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
Code:
package com.entitytest;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/app-context-hierarchy-test.xml"})
@Transactional
public class HierarchyTest {
@Autowired
private SessionFactory sessionFactory;
@Test
public void test() throws Exception {
Node parent = new Node();
sessionFactory.getCurrentSession().merge(parent);
System.out.println("parent id: " + parent.getId());
Node child = new Node();
child.setParent(parent);
sessionFactory.getCurrentSession().merge(child);
int manualCount = sessionFactory.getCurrentSession().createCriteria(Node.class)
.add(Restrictions.eq("parent", parent)).list().size();
assertEquals(1, manualCount);
Node result = (Node)sessionFactory.getCurrentSession().load(
Node.class, parent.getId());
assertNotNull(result.getChildren());
assertEquals(1, result.getChildren().size());
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}