Hello,
I have problem when mapping class that contains Map as its property: class Foo contains Map with own defined classes for Key and Value.
When I call session.getTransaction().commit(), I get TransientObjectException.
If I make change and also save all keys and values into session,
Code:
session.save(key1);
session.save(key2);
session.save(key3);
session.save(value1);
session.save(value2);
session.save(value3);
transaction is commited without exception.
When I have just String keys in Map, I haven't save values into session before saving foo.
Is there a way, how to go over this problem without need of saving all keys and values objects into session manually?
Thanks for any help.
Regards,
Miro
Hibernate version: 3.1.3 Mapping documents:--Foo.hbm.xml--
Code:
<hibernate-mapping>
<class name="foo.Foo" table="FOO">
<id name="id" column="FOO_ID">
<generator class="native" />
</id>
<map name="mapa" table="FOO_MAP" inverse="false">
<key column="FOO_ID" />
<index-many-to-many class="foo.MapKey" column="FOO_MAP_KEY" />
<!--index column="FOO_MAP_KEY" type="string" /-->
<!-- element column="MAP_VALUE" type="string" /-->
<many-to-many class="foo.MapValue" column="FOO_MAP_VALUE" />
</map>
</class>
</hibernate-mapping>
--MapKey.hbm.xml--
Code:
<hibernate-mapping>
<class name="foo.MapKey" table="MAP_KEY">
<id name="id" column="KEY_ID">
<generator class="native" />
</id>
<property name="mkey" />
</class>
</hibernate-mapping>
--MapValue.hbm.xml--
Code:
<hibernate-mapping>
<class name="foo.MapValue" table="MAP_VALUE">
<id name="id" column="VALUE_ID">
<generator class="native" />
</id>
<property name="value" />
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close(): Foo foo=new Foo();
Map<MapKey, MapValue> mapa=new HashMap<MapKey, MapValue>();
MapKey key1 = new MapKey("Key1");
MapKey key2 = new MapKey("Key2");
MapKey key3 = new MapKey("Key3");
MapValue value1 = new MapValue("Val1");
MapValue value2 = new MapValue("Val2");
MapValue value3 = new MapValue("Val3");
mapa.put(key1,value1);
mapa.put(key2,value2);
mapa.put(key3,value3);
foo.setMapa(mapa);
Full stack trace of any exception that occurs:Code:
org.hibernate.TransientObjectException: foo.MapKey
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:216)
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:108)
at org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:71)
at org.hibernate.persister.collection.AbstractCollectionPersister.writeIndex(AbstractCollectionPersister.java:707)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1034)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:26)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:143)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at foo.FooManager.createAndStoreFoo(FooManager.java:43)
at foo.FooManager.main(FooManager.java:53)
Name and version of the database you are using: Derby 10.1.3.1The generated SQL (show_sql=true):create table FOO (FOO_ID bigint not null, primary key (FOO_ID))
create table FOO_MAP (FOO_ID bigint not null, FOO_MAP_VALUE bigint not null, FOO_MAP_KEY bigint not null, primary key (FOO_ID, FOO_MAP_KEY))
create table MAP_KEY (KEY_ID bigint not null, mkey varchar(255), primary key (KEY_ID))
create table MAP_VALUE (VALUE_ID bigint not null, value varchar(255), primary key (VALUE_ID))
alter table FOO_MAP add constraint FK248A623FAF7E02E foreign key (FOO_MAP_KEY) references MAP_KEY
alter table FOO_MAP add constraint FK248A6231DB2AA52 foreign key (FOO_MAP_VALUE) references MAP_VALUE
alter table FOO_MAP add constraint FK248A6238BB61EB2 foreign key (FOO_ID) references FOO
create table hibernate_unique_key ( next_hi integer )
insert into hibernate_unique_key values ( 0 )
Debug level Hibernate log excerpt:Code:
20:09:27,656 DEBUG SQL:346 - insert into FOO_MAP (FOO_ID, FOO_MAP_KEY, FOO_MAP_VALUE) values (?, ?, ?)
Hibernate: insert into FOO_MAP (FOO_ID, FOO_MAP_KEY, FOO_MAP_VALUE) values (?, ?, ?)
20:09:27,656 DEBUG AbstractBatcher:424 - preparing statement
20:09:27,671 ERROR AbstractFlushingEventListener:300 - Could not synchronize database state with session
org.hibernate.TransientObjectException: foo.MapKey
...