0

When I am looking for @NaturalId and trying to understand what the advantages of using it is. I am reading several articles like this article.

@Entity(name = "Post")
@Table(name = "post")
@org.hibernate.annotations.Cache(
    usage = CacheConcurrencyStrategy.READ_WRITE
)
@NaturalIdCache
public class Post {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private String title;
 
    @NaturalId
    @Column(nullable = false, unique = true)
    private String slug;
 
    //Getters and setters omitted for brevity
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass())
            return false;
        Post post = (Post) o;
        return Objects.equals(slug, post.slug);
    }
 
    @Override
    public int hashCode() {
        return Objects.hash(slug);
    }
}

And when retrieving record, the following approach is used:

String slug = "high-performance-java-persistence";
 
Post post = entityManager.unwrap(Session.class)
    .bySimpleNaturalId(Post.class)
    .load(slug);

I am wondering that, what is I remove @NaturalId from the slug field and retrieve the record via bySlug method? As far as I see, @NaturalId acts as an index and may help to access the record faster I think. Is that true? Could you explain the benefits of it?

1 Answers1

0

I think the Hibernate ORM documentation explains the use of @NaturalId pretty well:

Natural ids represent domain model unique identifiers that have a meaning in the real world too. Even if a natural id does not make a good primary key (surrogate keys being usually preferred), it’s still useful to tell Hibernate about it.

When you mark a field as natural id, Hibernate creates a unique constraint for it in the database (if you generate it at start up) and caching using the field as key becomes possible. You can also use @NaturalIdCache to use the second-level cache. In general, it should lead to better performance when looking for the entity using the field.

Davide D'Alto
  • 7,421
  • 2
  • 16
  • 30
  • **#1** Do we have to add @NaturalIdCache annotation whenever we use NaturalId ? –  Aug 04 '22 at 10:56
  • **#2** As far as I see, @NaturalId annotation is used an index, but I am not sure if I should use it whenever I have a unique field in my entity. Any idea? –  Aug 04 '22 at 10:56
  • **#3** Can I use @NaturalId when both; the property is updatable or not? –  Aug 04 '22 at 10:56
  • About number 3, yes, you can use NaturalId even when the property is mutable. [It is explained in the docs](https://docs.jboss.org/hibernate/orm/5.6/userguide/html_single/Hibernate_User_Guide.html#naturalid-mutability-caching). – Davide D'Alto Aug 04 '22 at 11:03
  • WHat about other numbers? –  Aug 04 '22 at 11:08
  • If you know that the field must be unique, I think it makes sense to use it. But it depends on your use case. It might not make any difference if you never query that field. Same for using the second level cache. It's up to you to measure the performance. – Davide D'Alto Aug 04 '22 at 11:10
  • I guess having the index on the field might benefit all queries filtering using the field, so I don't see any particular disadvantage in using it. – Davide D'Alto Aug 04 '22 at 11:17
  • Thanks a lot. Voted up and marked as answer. –  Aug 04 '22 at 11:25