Hi all,
This is for sure a newbie question, but I could do with some help. I have a Game class and a Category class with a many-to-many table used so that a game can have many categories and vice-versa.
When I store the game, it shows that the categories are populated (via the debug, plus the database tables are populate properly), but when I retrieve the categories they don't have the games populated.
I intend to always add the category information directly to the game object, but think it will be useful to iterate through categories to see what games are in that category. To achieve this I have determine that the category has the 'inverse' keyword (since I will not be adding entities to this directly) and therefore the game one doesn't have the inverse attribute.
Additionally, I have the cascade on both set to 'save-update', although I *think* maybe I only need it on Game?
What am I missing?! Any tips will be appreciated.
Here's the debug output
Code:
17:08:04,848 DEBUG Printer:83 - listing entities:
17:08:04,848 DEBUG Printer:90 - com.ciderbob.common.User{id=8, email=adminUser, administrator=true, dob=29 October 2007, name=null, password=null}
17:08:04,849 DEBUG Printer:90 - com.ciderbob.common.Category{id=2, games=[], name=Category1}
17:08:04,849 DEBUG Printer:90 - com.ciderbob.common.Game{id=1, visible=true, description=This is game 1, name=Game1, categories=[com.ciderbob.common.Category#1, com.ciderbob.common.Category#2], purchasePrice=9.99}
17:08:04,849 DEBUG Printer:90 - com.ciderbob.common.Category{id=1, games=[], name=Category2}
The Game mapping file
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 package="com.ciderbob.common">
<class name="Game" table="game">
<id name="id" column="game_id">
<generator class="native"/>
</id>
<property name="name" type="string" column="name" unique="true"/>
<property name="visible" type="boolean" column="visible"/>
<property name="purchasePrice" type="double" column="price"/>
<property name="description" type="string" column="description"/>
<set name="categories" table="GAME_CATEGORY" cascade="save-update">
<key column="game_id"/>
<many-to-many column="category_id" unique="true" class="Category"/>
</set>
</class>
</hibernate-mapping>
The category mapping file
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 package="com.ciderbob.common">
<class name="Category" table="category">
<id name="id" column="category_id">
<generator class="native"/>
</id>
<property name="name" type="string" column="name" unique="true"/>
<set name="games" table="GAME_CATEGORY" inverse="true" cascade="save-update">
<key column="category_id" />
<many-to-many column="game_id" class="Game"/>
</set>
</class>
</hibernate-mapping>
Here's my test harness code...
Code:
Game game = new Game("Game1","This is game 1",true,new Double(9.99));
log.debug("game id before:"+game.getId());
session.save(game);
log.debug("game id after:"+game.getId());
game.getCategories().add(new Category("Category1"));
game.getCategories().add(new Category("Category2"));
session.save(game);
// Now check the game exists and that when
// retrieved back out of the database it contains
// the two categories
Criteria criteria = session.createCriteria(Game.class);
criteria.add(Expression.eq("name", "Game1"));
List results = criteria.list();
assertEquals(results.size(),1);
Game retrievedGame = (Game) results.get(0);
assertEquals("Game1", retrievedGame.getName());
assertEquals(2, retrievedGame.getCategories().size());
// Then perform a query for all categories, check that
// Category1 and Category2 exists.
criteria = session.createCriteria(Category.class);
criteria.add(Expression.eq("name", "Category1"));
results = criteria.list();
assertEquals(1, results.size());
criteria = session.createCriteria(Category.class);
criteria.add(Expression.eq("name", "Category2"));
results = criteria.list();
assertEquals(1, results.size());
// Now check that the category has restored the
// bi-directional reference to the game
Category restoredCategory = (Category) results.get(0);
Set<Game> games = restoredCategory.getGames();
assertEquals(1, games.size()); // << FAILS