如何在 Hibernate Search 中正确使用 @ContainedIn 注解?

How to correctly use @ContainedIn annotation in Hibernate Search?

我将 Hibernate 与 PostgreSQL 结合使用 和休眠搜索 (5.7.0.Alpha1) 使用 ElasticSearch (2.4.2).

我有两个 class:BookAuthor。 一本书可以有很多作者 一个作者可以创作不止一本书。

我这样注释 Book class:

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
    //...
}

问题是当作者更新时 (例如他们的名字改变),对应书的文件 在 ElasticSearch 中没有变化。

例如执行此代码后:

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);
    }
}

ElasticSearch 中的作者文档将得到更新, 但书籍文件不会改变:

{"_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"}]}}}

我读到,对于这种情况,我需要在 Author 端使用 @ContainedIn 注释, 所以我做了。为此我需要添加属性authoredBooks,我之前没有计划

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
    //...
}

但这并没有改变 Hibernate Search 的行为, 所以书籍文档仍然没有更新。 您能否就我可以做什么或检查什么提供一些提示?

I'm using Hibernate with PostgreSQL and Hibernate Search (5.7.0.Alpha1) with ElasticSearch (2.4.2).

首先要做的是升级到 Hibernate Search 的实际版本(不是 Alpha 或 Beta),以确保您没有遇到此后已解决的错误。

除此之外...您的初始代码仅更新关系的一侧;您确定在 ook01.addAuthor(author01) 之后添加 author01.addBook(book01) 行吗?