I'm having problems trying to map a many-to-many relationship between two classes.
I have a class called domain.Category and I have a class called domain.Agent. Agents can earn points in a given category and so a property of domain.Agent is a java.util.Map<Category, Integer> that stores the points that agent has in the specified Category which serves as the key for the Map.
Here's a look at what the classes look like:
Code:
class Category {
private Long id;
private String name;
public int hashCode() { return name.hashCode(); }
public boolean equals(Object o) {
Category c = (Category) o;
return c.name.equals(this.name);
}
}
class Agent {
private Long id;
private String name;
private Map<Category, Integer> agentCategoryPoints;
public int getPointsForCategory(final Category category) {
if (category == null) {
throw new IllegalArgumentException();
}
return agentCategoryPoints.get(category);
}
}
My mapping file seems to be at least somewhat correct because it *is* saving the data to the database correctly.
However whenever I try to reload an Agent instance that has Category scores properly saved from the database the agentCategoryPoints field doesn't actually get initialized with any values. Upon closer inspection after I load the Agent instance I can see that agentCategoryPoints is of type org.hibernate.collection.PersistentMap however it's size is 0 and it's not null, but when I try to do agentCategoryPoints I get a NullPointerException on the line where I call from with Agent:
return agentCategoryPoints.get(category);
The peculiar thing is that neither the category object nor the agentCategoryPoints object is null. I can see this in the debugger. When it loads the instance of Agent which has data that corresponds correctly to data previously saved for agentCategoryPoints in the agent_category_points table the agentCategoryPoints member field is set to an instance of org.hibernate.collection.PersistentMap with a size of 0. Setting lazy="false" for the agentCategoryPoints field mapping doesn't seem to help.
Hibernate version: 3.1.2 in conjunction with SpringFramework 1.2.6
Mapping documents:Code:
<hibernate-mapping default-access="field">
<class name="domain.Category" table="category">
<id name="id" column="category_id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="name" column="name" unique="true" length="50" not-null="true"/>
<!-- many-to-many join table for related categories (which are optional) -->
<set name="relatedCategories" table="related_tags" lazy="false">
<key column="category_id"/>
<many-to-many column="related_category_id" class="domain.Category"/>
</set>
</class>
<class name="domain.Agent" table="agent">
<id name="id" column="id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="name" column="name" length="50" not-null="true"/>
<map name="agentCategoryPoints" cascade="all,delete-orphan" inverse="true" table="agent_category_pts" lazy="false" access="field">
<key column="agent_id"/>
<map-key-many-to-many class="domain.Category" column="category_id" />
<element type="int" column="points" not-null="true"/>
</map>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():I'm doing a simple find by Id for the agent (using the Spring hibernate template):
Code:
final Agent agent = (Agent) getHibernateTemplate().get(AgentImpl.class, id);
Full stack trace of any exception that occurs:Code:
java.lang.NullPointerException
at domain.Agent.getPointsForCategory(Agent.java:108)
at domain.UserPersistenceIntegrationTest.testCreateUserAndAgent(UserPersistenceIntegrationTest.java:183)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:32)
Name and version of the database you are using:MySQL 5.0.18
Code:
Code:
Code:
Code:
Code: