首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用JPA、Hibernate、Springboot实现组合主键和组合外键

如何使用JPA、Hibernate、Springboot实现组合主键和组合外键
EN

Stack Overflow用户
提问于 2018-06-04 03:17:43
回答 1查看 661关注 0票数 0

我为这个特殊的问题找了很多,但我没有找到任何具体的解决方案。我在一个表中有一个组合主键,这个组合主键中的一个字段是另一个表的组合主键的一部分。您可以说这个特定字段是第二个表中的外键,但我没有在表定义中定义任何独占外键约束。对于第一个表中的每个记录,在第二个表中可以有多个记录。我正在尝试使用SPringBoot-JPA-Hibernate实现这一点,但无法实现。有人能帮我一下吗。详情如下:

我有一个包含以下字段的USER_CREDENTIAL表:

代码语言:javascript
复制
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)这是我的第二张表

代码语言:javascript
复制
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对应于两个不同表的主键结构:

对于INSTITUTION_USER_CREDENTIAL表:-

代码语言:javascript
复制
@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
}

对应的实体类:-

代码语言:javascript
复制
@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表:-

代码语言:javascript
复制
@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
}

实体类:-

代码语言:javascript
复制
@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
}

请注意,只有一个字段INSTITUTION_USER_ID在InstitutionUserCredentialMaster的复合PrimaryKey中使用,并且来自InstitutionUserCredential的复合主键。

当我运行我的代码时,这会给我一个错误,比如:-

代码语言:javascript
复制
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

代码语言:javascript
复制
@Embeddable

公共类InstituteUserCredentialMasterPrimaryKey实现了可序列化的{

代码语言:javascript
复制
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 :-

代码语言:javascript
复制
@Entity(name = "INSTITUTION_USER_CREDENTIAL_MASTER")

公共类InstitutionUserCredentialMaster {

代码语言:javascript
复制
@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;
}

这一次我得到一个错误,如下所示

代码语言:javascript
复制
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]
EN

回答 1

Stack Overflow用户

发布于 2018-06-04 03:33:49

我认为问题在于您没有在JoinColumns注释中引用EmbeddedId的另一部分。您已经定义了institutionUserName也是主键的一部分,因此在entity InstitutionUserCredentialMaster中的外键定义中也应该提到这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50670104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档