So I've built an Spring Application that has a Hibernate Search (Version 6.2.2.Final) Module. Through Docker I started an Elasticsearch (Version 8.9.1) Container alongside Enterprise Search and Kibana for management.
I am trying to index this Entity:
@Entity
@Indexed(index = "search-fileentity-new")
public class FileEntityHS {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@KeywordField
private String fileIdAsString;
@Transient
private transient long fileId;
@KeywordField
private String userIdAsString;
@Transient
private transient long userId;
@FullTextField
private String customName;
@ElementCollection
private List<String> tags;
@FullTextField()
private String content;
@KeywordField
private String fileGuid;
public FileEntityHS() {
this.fileId = 0L; // oder andere Default-Werte
this.userId = 0L;
this.fileIdAsString = "0";
this.userIdAsString = "0";
}
public FileEntityHS(long fileId, long userId, String customName, List<String> tags, String content, String fileGuid) {
this.fileId = fileId;
this.userId = userId;
this.customName = customName;
this.tags = tags;
this.content = content;
this.fileGuid = fileGuid;
this.fileIdAsString = Long.toString(this.fileId);
this.userIdAsString = Long.toString(this.userId);
}
}
And this is the Code I am trying to index with:
@Service
public class SearchServiceImpl implements SearchService {
private final EntityManager entityManager;
private final SearchSession searchSession;
public SearchServiceImpl(EntityManager entityManager) {
this.entityManager = entityManager;
this.searchSession = Search.session(entityManager);
}
@Override
@Transactional
public short indexFile(FileEntityHS file) {
try {
searchSession.indexingPlan().addOrUpdate(file);
} catch(Exception e) {
e.printStackTrace();
}
return 0;
}
}
In my Elasticsearch instance I have created an Index with the name thats specified in my Entity search-fileentity-new. For some reason Hibernate Search always re-creates an Index with -000001 at the end. For example search-fileentity-new-000001.
So the index with the last indexed document is deleted and a new index with the same name and with the indexed File is created. This is not expacted behaviour for me as documentation does not mention anything about this.
This is part of my pom.xml:
<properties>
<hibernate.version>6.2.2.Final</hibernate.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.search</groupId>
<artifactId>hibernate-search-mapper-orm-orm6</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate.search</groupId>
<artifactId>hibernate-search-backend-elasticsearch</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
I looked a bit around and found some things I've tried. In my .properties I have this:
# Hibernate Search
spring.jpa.properties.hibernate.search.backend.type=elasticsearch
hibernate.search.backend.type=elasticsearch
spring.jpa.properties.hibernate.search.backend.index_defaults.lifecycle.strategy=none
hibernate.search.backend.index_defaults.lifecycle.strategy=none
spring.jpa.properties.hibernate.search.index_schema_management.strategy=none
hibernate.search.index_schema_management.strategy=none
spring.jpa.properties.hibernate.search.schema_management.strategy=none
hibernate.search.schema_management.strategy=none
I thought maybe it's some kind lifecycle setting so I tried to disable everything in the .properties but it doesn't do anything.
Next I looked in Elasticsearch and there weren't any settings that suggested a lifecycle control in Elasticsearch for that index. But maybe I looked at the wrong place.
I've also stumbled upon another way to index documents with a MassIndexer:
SearchSession searchSession = Search.session(entityManager);
MassIndexer massIndexer = searchSession.massIndexer(FileEntityHS.class);
massIndexer.startAndWait();
But when I tried that Hibernate Search tried to persist the document in a Mysql Database. So that didn't work either.
Update 1
Okay, so one of the problems I mentioned was that the Index always gets recreated because it looked like it to me. But I noticed that this is not true in Fact the data in the Index gets overriten. As for indexnaming difference the property hibernate.search.backend.layout.strategy=simple (default) causes this behavior. I changed it to no-alias and now the specified Index in the entity is getting used.
But the problem that with every new
SearchSession.indexingPlan().addOrUpdate(Entity);
my data getting lost was still present.
Update 2
I was able to fix the overriding of the data. First I noticed that the id of the documents indexed is always 0. So I was lookig at how to define the id in the Entity. I found that you would not use Long as type instead you would use String.
That got me one step further. Now I got an error that stated that the length of the id was null. For that to get fixed I had to manuelly set the id for my documents.
...
import java.util.UUID;
@Entity
@Indexed(index = "search-fileentity-new")
public class FileEntityHS {
@Id
private String id;
...
public FileEntityHS() {
this.id = UUID.randomUUID().toString();
...
}
public FileEntityHS( ..., String fileGuid) {
this.id = fileGuid;
...
}
// getter and setter
So now data is getting indexed seperatly with there own DocumentId.
Note: Thanks to all People that shared their knowledge!
First, I'd recommend you start simple. You don't need to create the Elasticsearch index yourself, Hibernate Search can do it. Just remove all configuration and follow the getting started guide. Once that works, try something more complex.
Second, if you do want to create the index manually:
validate, notnone. This will tell you exactly what is wrong on startup, instead of leaving you in the dark like this. See https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#mapper-orm-schema-management-strategysearch-fileentity-new-writeandsearch-fileentity-new-read. See https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#backend-elasticsearch-indexlayoutI'm sorry but this doesn't make sense. Hibernate Search never persists documents in a database, the code to do that simply isn't there.
Judging from the strange behavior you're experiencing, if I were you I'd check that you're not starting an
EntityManagerFactorymanually somewhere. You're not supposed to do that, Spring should do that.