我使用三向连接表对地图进行了Hibernate(3.3.1)映射:
@Entity
public class SiteConfiguration extends ConfigurationSet {
@ManyToMany
@MapKeyManyToMany(joinColumns=@JoinColumn(name="SiteTypeInstallationId"))
@JoinTable(
name="SiteConfig_InstConfig",
joinColumns = @JoinColumn(name="SiteConfigId"),
inverseJoinColumns = @JoinColumn(name="InstallationConfigId")
)
Map<SiteTypeInstallation, InstallationConfiguration>
installationConfigurations = new HashMap<SiteTypeInstallation, InstallationConfiguration>();
...
}
基础表(在Oracle 11g中)是:
Name Null Type
------------------------------ -------- ----------
SITECONFIGID NOT NULL NUMBER(19)
SITETYPEINSTALLATIONID NOT NULL NUMBER(19)
INSTALLATIONCONFIGID NOT NULL NUMBER(19)
密钥实体过去在数据库中有一个三列主键,但现在重新定义为:
@Entity
public class SiteTypeInstallation implements IdResolvable {
@Id
@GeneratedValue(generator="SiteTypeInstallationSeq", strategy= GenerationType.SEQUENCE)
@SequenceGenerator(name = "SiteTypeInstallationSeq", sequenceName = "SEQ_SiteTypeInstallation", allocationSize = 1)
long id;
@ManyToOne
@JoinColumn(name="SiteTypeId")
SiteType siteType;
@ManyToOne
@JoinColumn(name="InstalationRoleId")
InstallationRole role;
@ManyToOne
@JoinColumn(name="InstallationTypeId")
InstType type;
...
}
这个表有一个主键'Id'和外键约束+每个其他列的索引:
Name Null Type
------------------------------ -------- ----------
SITETYPEID NOT NULL NUMBER(19)
INSTALLATIONROLEID NOT NULL NUMBER(19)
INSTALLATIONTYPEID NOT NULL NUMBER(19)
ID NOT NULL NUMBER(19)
出于某种原因,Hibernate认为地图的关键是复合的,即使它不是,并且给了我这个错误:
org.hibernate.MappingException:外键(FK1A241BE195C69C8:SiteConfig_InstConfig [SiteTypeInstallationId]))必须与引用的主键具有相同的列数(SiteTypeInstallation [SiteTypeId,InstallationRoleId])
如果我删除installationConfigurations
上的注释并使其成为瞬态,则错误消失。
我很困惑为什么当@Id清楚地定义一个简单的密钥时,它认为SiteTypeInstallation有一个复合密钥,并且更加困惑为什么它只选择这两个列。知道为什么会这样吗?是否有可能JBoss(5.0 EAP)+ Hibernate以某种方式记住了服务器重启和代码重新部署的主键错误概念?
提前致谢, -Lars