I can see that using an idbag on a many-to-many association is supported and people do use it, but I'm having a problem. I've searched google, jira, and this forum back to 2006, and found nothing similar. Can anyone help?
I'm using JPA2 and Hibernate 3.5.1-final with annotations.
Here's my association mapping:
Code:
@CollectionId(
columns =
{
@Column(
name = "organization_market_segment_id", columnDefinition = "uniqueidentifier",
nullable = false
)
}, type = @Type(type = "string"), generator = "sequential-guid"
)
@ForeignKey(
inverseName = "FK_organization_market_segment_market_segment",
name = "FK_organization_market_segment_organization"
)
@ManyToMany
public Collection<MarketSegment> getMarketSegments() {
return marketSegments;
}
(I also tried using List as opposed to Collection.)
I get this output when saving the addition of an element to the collection.
Code:
Hibernate: insert into odd.organization_market_segment (organization_id, organization_market_segment_id, market_segment_id) values (?, ?, ?)
TRACE StringType - binding '60EB429E-775F-DF11-A72E-545543445203' to parameter: 1
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at org.hibernate.type.StringType.toString(StringType.java:67)
at org.hibernate.type.NullableType.nullSafeToString(NullableType.java:117)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:158)
at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:136)
at org.hibernate.persister.collection.AbstractCollectionPersister.writeIdentifier(AbstractCollectionPersister.java:868)
at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:1199)
at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:58)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:183)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:791)
...
I stepped through the hibernate code using a debugger and it appears that hibernate is getting confused.
Here's a snippet from AbstractCollectionPersister.recreate(...):
Code:
int loc = writeKey( st, id, offset, session );
if ( hasIdentifier ) {
loc = writeIdentifier( st, collection.getIdentifier(entry, i), loc, session );
}
The error occurs when AbstractCollectionPersister tries to get the surrogate key value for the second parameter - the last line of code above. But that call to getIdentifier(...) on the collection (a PersistentIdentifierBag) returns the @Id value of the associated object, MarketSegment - which should be the third parameter to the PreparedStatement. This value is an Integer @Id, but the calling context correctly expects a String, so a ClassCastException occurs.