我目前正在尝试使用Credential对象的JPARepository接口执行持久化,该接口具有复合键作为主键。 回购是:
@Transactional
public interface CredentialRepository extends JpaRepository<Credential,CredentialPK> {}
credentialPK是:
@Embeddable
public class CredentialPK implements Serializable {
@Column(name = "CREDENTIAL_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer credentialID;
@Column(name = "CREDENTIAL_TYPE_ID")
private String credentialTypeID;
public CredentialPK() {
}
//getters and setters;
}`
凭证:
@Entity
@Table(name = "TBL_CREDENTIALS")
public class Credential {
@EmbeddedId
private CredentialPK credentialPK;
//getters and setters
}
在服务类中,我尝试使用应用程序提供的凭据类型执行保存操作。让我们说,为了示例,凭证类型是“临时的”。 创建和保存凭证的代码如下:
Credential credential = new Credential();
CredentialPK pk = new CredentialPK();
pk.setCredentialTypeID("temporary");
credential.setCredentialPK(pk);
Credential temporaryCredential = credentialRepository.saveAndFlush(credential);
temporaryCredential.getCredentialPK().getCredentialID(); // returns null, even when repository is flushed
`
我要求 temporaryCredential 使用新插入的凭据的ID填充凭据ID。但是,获取的凭证ID为空。我尝试使用 CrudRepository api和 JpaRepository api进行存储库实施,同时保存和 saveAndFlush 方法。如果凭证的主键不是复合的,那么这非常有效,但由于遗留代码,我无法进行此更改。
有什么建议吗?
答案 0 :(得分:2)
从另一个答案:How to get auto generated value from composite primary key in hibernate
我一直徘徊在万维网上的所有可能的链接上,并试图找到为什么你不能将@GeneratedValue与@EmbeddedId或@IdClass(即复合PK)一起使用。原因是你不能。
复合PK基于ASSIGNMENT而不是基于GENERATION。因此,任何@GeneratedValue内容都不适用于它们。我的项目也有问题,我认为没有其他方法
如果您知道您的@GeneratedValue ID在您的域(例如,您的数据库)的上下文中始终是唯一的,则您不需要使用复合PK并进行一些内部检查以确定记录的唯一性
所以,就像这张海报所说,如果你有@GeneratedValue
,你不需要复合PK,生成的值是唯一的。永远不会有creditialId
和credentialTypeId
的任何组合可能是非唯一的。这基本上意味着你需要重新考虑你的设计,恕我直言。