我们的物理数据模型如下所示
USER
user_id (...other attributes)
ORGANIZATION
organization_id (...other attributes)
USER_ORG_ATTRIBUTES
user_id org_id email
我们有以下Hibernate映射
@Entity
@Table(name = "USER")
public class UserEntity {
@Id
@Column(name = "USER_ID")
private int userId;
@ElementCollection
@CollectionTable(name = "USER_ORG_ATTRIBUTES",
joinColumns = @JoinColumn(name = "USER_ID"))
@MapKeyJoinColumn(name = "ORGANIZATION_ID")
private Map<OrganizationEntity, UserOrgAttributes> userOrgAttributes;
}
@Entity
@Table(name = "ORGANIZATION")
public class OrganizationEntity {
@Id
@Column(name = "ORGANIZATION_ID")
private int organizationId;
}
@Embeddable
public class UserOrgAttributes {
@Column(name = "EMAIL")
private String email;
public String getEmail() {
return email;
}
public void setEmail(final String email) {
this.email= email;
}
}
我们使用Embeddable来映射USER_ORG_ATTRIBUTES,因为我们希望稍后添加更多列。
在DAO层,我们创建一个Transient UserEntity对象(当前不由Hibernate管理),然后调用session.merge(userEntity)。我们在Hibernate属性中启用了show_sql,我们注意到它总是删除USER_ORG_ATTRIBUTES上的所有记录,其中user_id = userEntity的ID值,然后为新行插入user_id,organization_id和email值。理想情况下,我们希望这是“更新”而不是“删除/插入”。
此外,它插入的行数少于预期。假设我们有以下数据
USER_ORG_ATTRIBUTES
user_id org_id email
1 2 abc@xyz.com
1 3 (null)
要保留的Transient userEntity在userOrgAttributes映射中有2个条目,其中一个键是OrganizationEntity,其organizationId = 2,值为UserOrgAttribute的一个实例,其中email ='abc@xyz.com'。第二个条目的键为organizationId = 3,值为email = null。
当Hibernate合并此实体时,它会删除这两行,但只会插入一行,即电子邮件为空的行(organizationId = 3)。
现在假设我们有
USER_ORG_ATTRIBUTES
user_id org_id email
1 3 (null)
在地图中保留同一个userEntity和2个条目,我们得到一个删除,然后是2个插入!
显然,我们每次都会期待2次插入或2次更新。如果有帮助的话,这就是Hibernate 4.2。