I have a jpa entity "user" which has 2 business keys username and email. These 2 fields are unique and i have tried to define both fields as naturalId with @NaturalId, however when i search the user entity by passing only username or email, hibernate throw an exception complaining about the missing value of a another naturalid because hibernate treated both fields as a composite natural id. Is this the limitation of hibernate or there is an alternative to solve this error?
@Entity
@Table(name = "user",
indexes = { @Index(columnList = "login"),
@Index(columnList = "email")},
uniqueConstraints = { @UniqueConstraint(columnNames = { "login" }),
@UniqueConstraint(columnNames = { "email" })})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@org.hibernate.annotations.NaturalIdCache
public class User {
@org.hibernate.annotations.NaturalId(mutable = true)
private String login;
@org.hibernate.annotations.NaturalId(mutable = true)
private String email;
...
}
When I call the code below:
User entity = em.unwrap(Session.class)
.byNaturalId(User.class)
.using("login", "abc123")
.load();
or
User entity = em.unwrap(Session.class)
.byNaturalId(User.class)
.using("email", "abc123@xyz.com")
.load();
I encountered error complaining about missing of another natural id. I have to set both natural id which was not what i want
User entity = em.unwrap(Session.class)
.byNaturalId(User.class)
.using("login", "abc123")
.using("email", "abc123@xyz.com")
.load();
This concept does not support more than one business keys.
As you said, annotating multiple properties with @NaturalId means that this sole business key consists of multiple properties (javadoc citation):
This specifies that a property is part of the natural id of the entity.
Also rest of the API somewhat communicates the same.
For example SimpleNaturalIdLoadAccess
is created via bySimpleNaturalId(Class entityClass) and load in SimpleNaturalIdLoadAccess
takes value of natural id as an argument. There is no way to specify which natural id.