我目前正试图使用Credential对象的JPARepository接口执行持久化,该接口将复合键作为主键。回购是:
@Transactional
public interface CredentialRepository extends JpaRepository<Credential,CredentialPK> {}
凭证PK为:
@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
`
我要求临时凭证具有用新插入凭证的id填充的凭证id。但是,我得到的凭证ID为空。我已经尝试将CrudRepositoryapi和JpaRepositoryapi用于存储库实现,同时使用save和saveAndFlush方法。如果凭证的主密钥不是复合的,这将非常有效,但由于遗留代码的原因,我无法进行此更改。
有什么建议吗?
另一个答案:如何在hibernate 中从复合主键中获得自动生成的值
我一直在浏览万维网上所有可能的链接,试图找出为什么不能将@GeneratedValue与@EmbeddedId或@IdClass(即复合PK)一起使用。原因是你不能。
复合包装是基于分配而非基于生成的。因此,任何@GeneratedValue的东西都不应该与它们一起工作。我的项目也有问题,我认为没有其他方法
如果你知道你的@GeneratedValue ID在你的域(例如,你的数据库)的上下文中总是唯一的,你不需要使用复合PK,也不需要进行一些内部检查来确定你的记录的唯一性
所以,就像这张海报所说的,如果你有一个@GeneratedValue
,你不需要一个复合PK,生成的值是唯一的。CCD_ 4和CCD_。这基本上意味着你需要重新思考你的设计,IMHO。