[英]How to implement Composite Primary key and Composite Foreign Key using JPA,Hibernate, Springboot
我为此问题进行了大量搜索,但没有找到任何具体解决方案。 我在一个表中有一个复合主键,此复合主键中的一个字段是另一张表的复合主键的一部分。 您可以说该特定字段是第二个表中的外键,但是在表定义中未定义任何排他性外键约束。 在第二个表中,对于第一个表中的每个记录,可能有多个记录。我正在尝试使用SPringBoot-JPA-Hibernate来实现此功能,但无法这样做。 可以帮我一下吗? 这是detais:-
我有一个带有以下字段的USER_CREDENTIAL表:-
CREATE TABLE `INSTITUTION_USER_CREDENTIAL` (
`INSTITUTION_USER_ID INT(10) NOT NULL, -> AutoGeneratd
`INSTITUTION_USER_NAME` VARCHAR(50) NOT NULL,
`INSTITUTION_USER_PASSWORD` VARCHAR(50) NOT NULL,
`FIRST_NAME` VARCHAR(100) NOT NULL,
`MIDDLE_NAME` VARCHAR(100),
`LAST_NAME` VARCHAR(100) NOT NULL,
PRIMARY KEY (`INSTITUTION_USER_ID`,`INSTITUTION_USER_NAME`)
);
2)这是我的第二张桌子
CREATE TABLE `INSTITUTION_USER_CREDENTIAL_MASTER` (
`INSTITUTION_ID` INT(10) NOT NULL, -> Autogenerated
`INSTITUTION_USER_ID` INT(10) NOT NULL, -> Coming from
INSTITUTION_USER_CREDENTIAL
`INSTITUTION_USER_ROLE` CHAR(02) NOT NULL,
`INSTITUTION_USER_STATUS` CHAR(02) NOT NULL,
`INSTITUTION_NAME` VARCHAR(200) NOT NULL,
`LAST_UPDT_ID` VARCHAR(100) NOT NULL,
`LAST_UPDT_TS` DATETIME NOT NULL,
PRIMARY KEY(`INSTITUTION_ID`,`INSTITUTION_USER_ID`,`INSTITUTION_USER_ROLE`)
);
请注意,我没有在第二张表中声明任何特定的外键。 我有两个@Embeddable Class对应于两个不同表的两个主键结构:
对于INSTITUTION_USER_CREDENTIAL表:
@Embeddable
public class InstitutionUserCredentialPrimaryKey implements Serializable{
private static final long serialVersionUID = 1L;
@Column(name = "INSTITUTION_USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int institutionUserId;
@Column(name = "INSTITUTION_USER_NAME")
private String institutionUserName;
//Getter-Setters removed for clarity
}
对应实体类:
@Entity(name = "INSTITUTION_USER_CREDENTIAL")
public class InstitutionUserCredential {
@EmbeddedId
private InstitutionUserCredentialPrimaryKey
institutionUserCredentialPrimaryKey;
@Column(name = "INSTITUTION_USER_PASSWORD")
private String instituteUserPassword;
@Column(name = "FIRST_NAME")
private String firstname;
@Column(name = "MIDDLE_NAME")
private String middleName;
@Column(name = "LAST_NAME")
private String lastName;
@OneToMany(mappedBy="institutionUserCredential", cascade = CascadeType.ALL)
private List<InstitutionUserCredentialMaster>
institutionUserCredentialMaster;
//Getter-Setter and other part of the code removed for clarity
}
对于INSTITUTION_USER_CREDENTIAL_MASTER表:
@Embeddable
public class InstituteUserCredentialMasterPrimaryKey implements Serializable
{
private static final long serialVersionUID = 1L;
@Column(name = "INSTITUTION_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int institutionId;
@Column(name = "INSTITUTION_USER_ID")
private int institutionUserId;
@Column(name = "INSTITUTION_USER_ROLE")
private String userRole;
//Getter-Setter and other part of the code removed for clarity
}
实体类别:-
@Entity(name = "INSTITUTION_USER_CREDENTIAL_MASTER")
public class InstitutionUserCredentialMaster {
@EmbeddedId
private InstituteUserCredentialMasterPrimaryKey
instituteUserCredentialMasterPrimaryKey;
@Column(name = "INSTITUTION_USER_STATUS")
private String userStatus;
@Column(name = "INSTITUTION_NAME")
private String institutionName;
@Column(name = "LAST_UPDT_ID")
private String lastUpdateId;
@Column(name = "LAST_UPDT_TS")
private String lastUpdateTimestamp;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="institutionUserId", referencedColumnName =
"INSTITUTION_USER_ID")
})
private InstitutionUserCredential institutionUserCredential;
//Getter-Setter and other part of the code removed for clarity
}
请注意,只有1个字段INSTITUTION_USER_ID在InstitutionUserCredentialMaster的组合主键中使用,并且来自InstitutionUserCredential的组合主键。
当我运行我的代码时,这给了我一个错误:-
Invocation of init method failed; nested exception is
org.hibernate.AnnotationException:
referencedColumnNames(INSTITUTION_USER_ID) of com.bnl.application.entity.InstitutionUserCredentialMaster.institutionUserCredential referencing com.bnl.application.entity.InstitutionUserCredential not mapped to a single property
到目前为止,我所看到的涉及“复合主键”和“外键”的示例中没有一个没有处理任何特定字段,而是更多地涉及整个键结构。 我正在使用MYSQL,我检查了是否可以创建具有复合主键的表,并且该复合键中的字段之一是另一个表中的外键,也是第二个表的复合主键的一部分。
任何指针赞赏
更新:-在我的第一篇文章中,我在发布它时犯了一个错误。 抱歉, institutionUserName
成为InstitutionUserCredentialMaster
的一部分。 这是一个错字。 InstitutionUserCredentialMaster
表中不存在intitutionUserName
。 我已经修复并更新了帖子。
*****根据Niver和Wega的输入进行更新*****
更新到InstitutionUserCredentialMasterPrimaryKey
@Embeddable
公共类InstituteUserCredentialMasterPrimaryKey实现了Serializable {
private static final long serialVersionUID = 1L;
@Column(name = "INSTITUTION_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int institutionId;
@Column(name = "INSTITUTION_USER_ID")
private int institutionUserId;
// Added the institutionUserName
@Column(name = "INSTITUTION_USER_NAME")
private String institutionUserName;
@Column(name = "INSTITUTION_USER_ROLE")
private String userRole;
}
更新到实体类InsstitutionUserCredentialMaster:-
@Entity(name = "INSTITUTION_USER_CREDENTIAL_MASTER")
公共类InstitutionUserCredentialMaster {
@EmbeddedId
private InstituteUserCredentialMasterPrimaryKey instituteUserCredentialMasterPrimaryKey;
@Column(name = "INSTITUTION_USER_STATUS")
private String userStatus;
@Column(name = "INSTITUTION_NAME")
private String institutionName;
@Column(name = "LAST_UPDT_ID")
private String lastUpdateId;
@Column(name = "LAST_UPDT_TS")
private String lastUpdateTimestamp;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
@JoinColumn(name="institutionUserId", referencedColumnName = "INSTITUTION_USER_ID"),
@JoinColumn(name="institutionUserName",referencedColumnName = "INSTITUTION_USER_NAME")
})
private InstitutionUserCredential institutionUserCredential;
}
这次我遇到了类似的错误
Invocation of init method failed; nested exception is org.hibernate.DuplicateMappingException: Table [institution_user_credential_master] contains physical column name [institution_user_id] referred to by multiple physical column names: [institutionUserId], [INSTITUTION_USER_ID]
我认为问题在于您没有在JoinColumns
批注中引用EmbeddedId
的另一部分。 您已经定义了institutionUserName
也是主键的一部分,因此在实体InstitutionUserCredentialMaster
的外键定义中也应提及它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.