Scenario
I'm having an Entity with a composite primary key as below. Also a repository with exists
and delete
operations using the tokeId
composite key as below.
@Entity
@IdClass(TokenId.class)
@NoArgsConstructor
@AllArgsConstructor
public class Token {
@Id
private String setId;
@Id
private String id;
@NotNull
private long expiration;
private boolean active;
private boolean setActive;
}
@Repository
public interface TokenRepositorySql extends JpaRepository<Token, TokenId> {
@Transactional
void deleteByIdIn(List<TokenId> id);
boolean existsByIdAndActiveTrueAndExpirationGreaterThan(TokenId tokenId, long currentTimestamp);
Issue
In both delete and exists functions, hibernate fails to map Id
as TokenId
. Rather it's expecting a String
id. Below is the exception.
Parameter value element [com.abc.security.token.repository.sql.entity.TokenId@458c58e3] did not match expected type [java.lang.String (n/a)]
Workaround
If I pass the values of the composite key separately in the repository, this seems to be working. But I want a way to use the composite key straightly.
Any help is highly appreciated.
P.S.
I've also found this unanswered question in the SO.
Cheers.
CodePudding user response:
@Embeddable
and @EmbeddedId
annotations can serve the purpose here.
First, you can annotate your TokenId
class with @Embeddable
class level annotation as follows:
@Embeddable
public class TokenId {
@Column(name="field1")
private String field1;
@Column(name="field2")
private String field2;
}
Then use the above Embeddable class as embeddedId in parent class as follows:
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Token {
@EmbeddedId
private TokenId id;
@NotNull
private long expiration;
private boolean active;
private boolean setActive;
}