I'm using Hibernate with PostgreSQL
and Hibernate Search (5.7.0.Alpha1)
with ElasticSearch (2.4.2).
I have two classes: Book and Author.
A book can have many authors
and an author can author more than one book.
I annotated Book class like this:
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
import org.hibernate.search.annotations.*;
@Indexed
@Entity
public class Book implements Record {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
protected Long id;
@Field
protected String title;
@ManyToMany
@JoinTable(name = "books_authors",
joinColumns = @JoinColumn(name = "book_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "author_id", referencedColumnName = "id"))
@IndexedEmbedded(includeEmbeddedObjectId = true)
protected List<Author> authors = new ArrayList<>();
//constructors, getters and setters
//...
}
The problem is that when an author gets updated (for example their name changes), the document of the correspoding book does not change in ElasticSearch.
For example after executing this code:
package com.example.app;
import com.example.app.model.Author;
import com.example.app.model.Book;
import com.example.app.model.Category;
import java.io.IOException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class App
{
public static void main(String[] args) throws IOException
{
SessionFactory sessionFactory = new Configuration().configure()
.buildSessionFactory();
Author author01 = new Author("Author 01");
Book book01 = new Book("Book 01");
book01.addAuthor(author01);
{
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(author01);
session.save(book01);
session.getTransaction().commit();
session.close();
}
author01.setName("Author 02");
{
Session session = sessionFactory.openSession();
session.beginTransaction();
session.saveOrUpdate(author01);
session.getTransaction().commit();
session.close();
}
//without this the app won't end
System.exit(0);
}
}
the author document in ElasticSearch will get updated, but the book document will not change:
{"_index":"com.example.app.model.author","_type":"com.example.app.model.Author","_id":"2","_score":1,
"_source":{"name":"Author 02"}}
{"_index":"com.example.app.model.book","_type":"com.example.app.model.Book","_id":"3","_score":1,
"_source":{"title":"Elementy","authors":[{"name":"Author 01", "id":"2"}]}}}
I read that for the situations like this I need to use @ContainedIn annotation at the Author side,
so I did. For this reason I needed to add the property authoredBooks, I didn't plan it before.
package com.example.app.model;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
import org.hibernate.search.annotations.*;
@Indexed
@Entity
public class Author {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
protected long id;
@Field
protected String name;
@ContainedIn
@ManyToMany(mappedBy = "authors")
private List<Book> authoredBooks = new ArrayList<>();
//constructors, getters and setters
//...
}
This however did not change the behaviour of Hibernate Search, so book document is still not updated. Could you give some hints on what can I do or check?