views:

121

answers:

3

Hi Guys,
I'm facing a problem with Hibernate. My current project is a little game. In this game you have a Board which has many Fields each with a Token.
I can make a select on an empty database without any problems but if I put one object into it (saving works without any exceptions and after it the database values looks good) I'm getting exceptions.
The interesting part in the Board class:

@OneToMany(fetch=FetchType.EAGER)
@MapKey(name = "point")
public Map<Point, Field> getGameMatrix() {
     return gameMatrix;
}

My query for getting the boards:

return getHibernateTemplate().loadAll(Board.class);

The log now comes up with this:

Hibernate: select this_.id as id0_2_, this_.uniqueClassName as uniqueCl3_0_2_, this_.borderDimension as borderDi4_0_2_, this_.dimension as dimension0_2_, this_.TYPE as TYPE0_2_, gamematrix2_.Board_id as Board1_4_, field3_.id as gameMatrix2_4_, (select a11.point from Field a11 where a11.id=gamematrix2_.gameMatrix_id) as formula0_4_, field3_.id as id1_0_, field3_.point as point1_0_, field3_.token_id as token3_1_0_, token4_.id as id2_1_, token4_.name as name2_1_, token4_.uniqueClassName as uniqueCl4_2_1_, token4_.TYPE as TYPE2_1_ from Board this_ left outer join Board_Field gamematrix2_ on this_.id=gamematrix2_.Board_id left outer join Field field3_ on gamematrix2_.gameMatrix_id=field3_.id left outer join Token token4_ on field3_.token_id=token4_.id

Until there it looks good, but then Hibernate does the following:

Hibernate: delete from Board_Field where Board_id=?  
Hibernate: insert into Board_Field (Board_id, gameMatrix_id) values (?, ?)

And I got this exception:

Exception in thread "AWT-EventQueue-0" org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: Field; nested exception is org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: Field

I'm not understanding why it makes the delete statement.
Any ideas?
thanks

A: 

Seems to me you are adding a Field object to the collection of Fields in the Board class, but you have to persist the new Field object first (you are probably new'ing it)

Hence the exception message: object references an unsaved transient instance - save the transient instance before flushing: Field

Hans Westerbeek
I'm doing this,I don't get the exception when I want to save a board. Saving boards works and the values in the database are fine. I'm getting the exception when I want select all boards.
funny
A: 

Hi. A workmate of mine had a similar problem. He's not now but the thing was related to database integrity.

It seems Hibernate had more constraints defined that the database. When it loaded some data, Hibernate saw that some record in the database must not exist, and tried to delete it.

Try to check if some should-be-but-not-defined foreign key is being violated and try to make consistent the data.

helios
A: 

You need to set the cascade attribute:

@OneToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL)
@MapKey(name = "point")
public Map<Point, Field> getGameMatrix() {
     return gameMatrix;
}

And you also need to override hashCode() and equals() for Point and Field - let your IDE (Eclipse, NetBeans, IntelliJ) generate them for you, using their business key (i.e. not their auto-generated ID)

Bozho