Its a little late for an answer, but maybe it might help somebody else.
When you add a new row to your collection with composite keys, you assign directly the ids. From this point on, Hibernate thinks that this row already exists in the database, it has already a primary key set. This causes Hibernate to do an UPDATE instead of an INSERT. But an call to UPDATE in the database returns that "0 rows have been updated". Hibernate expects 1 row to beupdated. This causes the error.
Well now to the solution. I don't know if this works for Hibernate, but it worked for NHibernate pretty well.
1. Create an Interceptor that does something like this one:
Code:
Public Function OnLoad(ByVal entity As Object, ByVal id As Object, ByVal state() As Object, ByVal propertyNames() As String, ByVal types() As NHibernate.Type.IType) As Boolean Implements NHibernate.IInterceptor.OnLoad
If TypeOf entity Is BaseCompositeIdEO Then
CType(entity, BaseCompositeIdEO).isSaved = True
End If
Return False
End Function
Public Function OnSave(ByVal entity As Object, ByVal id As Object, ByVal state() As Object, ByVal propertyNames() As String, ByVal types() As NHibernate.Type.IType) As Boolean Implements NHibernate.IInterceptor.OnSave
If TypeOf entity Is BaseCompositeIdEO Then
CType(entity, BaseCompositeIdEO).isSaved = True
End If
Return False
End Function
Public Function IsUnsaved(ByVal entity As Object) As Object Implements NHibernate.IInterceptor.IsUnsaved
If TypeOf entity Is BaseCompositeIdEO Then
Return Not CType(entity, BaseCompositeIdEO).isSaved
Else
Return Nothing
End If
End Function
then add the following to each EO that has a composite key
Code:
Private _isSaved As Boolean = False
Public Overridable Property isSaved() As Boolean
Get
Return _isSaved
End Get
Set(ByVal value As Boolean)
_isSaved = value
End Set
End Property
This will help Hibernate to find out, if it should be updated or inserted.
Be carefull: I added the code to a BaseCompositeIdEO class, which made it easy for me to find out, if the class supports the functions in the interceptor. If you don't want to put it in a seperate class, define an interface and change the code in the interceptor to check if the current EO supports the interface
Now all you have to do is to register the interceptor to the current session and thats it.
Sorry for not writing Java-Code, but hopefully this is helpfull for you.