3

There have some article on natural identifier and I read there that natural identifier boosts lookup for mostly used fields in hibernate. In this post, they described that natural identifier is far more better for looking up any data using a particular field. They also described that natural identifier is indexed by hibernate and hibernate boosts lookup performance by using that index.

As far I know there have also some way to create index for a particular field and using this way lookup performance can be earned. So what is the advantage of using natural identifier over general indexing?

For an example I can create an entity class having proper indexing like,

@Entity
@Table(name = "users", indexes = {
    @Index(columnList = "username", name = "users_username")
})
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "username", unique = true)
    private String username;

    @Column(name = "email_id")
    private String email;

    ------------

}

Other way I can create an entity having no indexing but natural identifier like,

@Entity
@Table(name = "users")
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @NaturalId
    @Column(name = "username", unique = true)
    private String username;

    @Column(name = "email_id")
    private String email;

    ------------

}

By definition both are working in same way and both are using indexing approach under the hood. So technically what is the difference between indexing and natural identifier? Which is recommended approach and how it's better over another?

ashikuzzaman
  • 54
  • 1
  • 6

1 Answers1

2

When you use @NaturalId, Hibernate will maintain a mapping of the natural ids to primary keys. For example, if you have a User entity like the following:

//This is pseudo-code

User {
@Id
long id;

@NaturalId
String username;
}

Hibernate will store which usernames map to which ids, which means if an entity is already associated with the session object, Hibernate can load it from the session by natural id. (This capability can also be extended to the 2nd level cache).

Indexing will create an additional column that keeps all of the rows of the original indexed column in a sorted order. Binary search can be conducted on the indexed column to reduce the number of rows examined for a look up.

I believe unique constraints automatically indexes the corresponding column in Postgres. I personally use both unique constraint and natural id annotations.

Solace
  • 2,161
  • 1
  • 16
  • 33
  • Thank you very much. As you said, natural identifier has some extra benefit over indexing and indexing has some extra overload than natural identifier. So, what would you like to recommend? Should I use natural identifier and leave using indexing? – ashikuzzaman Jul 30 '17 at 00:20
  • 1
    The two are not mutually exclusive. NaturalId is used by Hibernate internally when loading objects. The Index annotation is used during schema creation. If your schema is generated by Hibernate, then when Hibernate sees an Index annotation, it will create an index for that column (in the database). For unique fields that are commonly queried, I would recommend using @naturalid and @column(name="...", unique=true) – Solace Jul 30 '17 at 00:51