Not Auto-generating id for Long type but for String type field in Spring Data Elasticsearch

I am using spring boot application of version 1.5.6.RELEASE and spring-boot-starter-data-elasticsearch of the same version.

I have a model Greeting as like :

@Document(indexName = "index", type = "greetings")
public class Greeting implements Serializable{
    @Id
    private Long id;
    private String username;
    // Getter, Setter and constructor added here
}

My controller and service classes are same for the below cases without the type of id.

When I have sent the below post request:

curl -H "Content-Type: application/json" -X POST -d '{"username":"sunkuet02","message": "this is test"}' http://localhost:8080/api/greetings

It replies:

{"id":null,"username":"sunkuet02","message":"this is test"}

Then I have changed the Greeting class changing the type of id to String.

@Document(indexName = "index", type = "greetings")
public class Greeting implements Serializable{    
    @Id
    private String id;    
    private String username;
    // Getter, Setter and constructor added here
}

Clean, build and send the same post request:

curl -H "Content-Type: application/json" -X POST -d '{"username":"sunkuet02","message": "this is test"}' http://localhost:8080/api/greetings

And got the below response :

{"id":"AV2cq2OXcuirs1TrVgG6","username":"sunkuet02","message":"this is test"}

The scenario is : When the type of id field is Long then it doesn’t generate id automatically but if the type is String then it generates id automatically.

My questions are:

  • What is the actual reason ?
  • Does spring-data-elasticsarch always uses id field of type String ?
  • Is there any way in configuration to use id of type Long without adding any annotations.

Spring Data Elasticsearch uses _id internally as Id and _id type is String. When you used @Id on your document field, and your data type is String, spring data ES mapped its internal _id to your fields. But when you use numeric (Long, Integer, etc.) data type, spring data ES can’t map its auto-generated _id to your @Id field. If you see your document on ES, you will see that your document id field is null, and _id get’s auto-generated value.

What you can do is, generate your own id and set it in your document, then spring data ES will set the String value of that field in its internal _id field. And you will see your document id field contains the value you set.

I’ll explain this part:

What is the actual reason ?
Does spring-data-elasticsarch always uses id field of type String ?

Ids generated by default by Elasticsearch are 20 character long, URL-safe, Base64-encoded GUID strings.

The reason is, of course, performance – using modified Flake IDs allows to increase the number of lookups per second while indexing data. Generally speaking – the segment-base nature of Lucene promotes IDs that have some pattern in the way they are assigned to segments or have some predictability.

So if your application does not really care how the id should look like, it’s better to stick to the default ids provided by Elsticsearch.

More information in this article, section Use auto id or pick a good id.