When mapping a set of elements, ORM makes the key column of the set and all columns of the elements as primary key. This is problematic when the element type is mapped with a CompositeUserType. When mapping with a composite user type, each column of that type could be mapped as nullable (not-null="false"). ORM assumes nullable columns not to be part of the primary key, since primary keys must not consist of null values. However this causes bugs in two situations:
When Hibernate generates the schema, a primary key is generated for the table where the set elements are stored. Since nullable columns are not part of that key, two elements which only differ in nullable column cannot be added to the set.
When removing an element of a set, such that the set is not empty after the removal, Hibernate generates a sql delete statement which only considers the primary key. When a set contains two elements which only differ in a nullable column and one of these elements is removed from the set, both elements will be removed from the database table.
I believe that the assumption, that the table for set elements must have a primary key, is wrong. A value object, in contrast to an entity, must not define a unique, non-null identifier.
To fix these bugs the schema generator should not generate the primary key constraint. To fix the removal of set elements, the set could be "rebuild" by first remove all elements which can be efficently done with owning entity id and then insert the remaining elements of a set. Otherwise, a SQL statement should be generated which considers the nullable columns as well. The second approach could be problamatic because of the special handling of null-values in SQL (<column> is null instead of <column>=<value>).