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

时间:2017-07-20 15:20:29

标签: java elasticsearch hibernate-search

我正在使用Hibernate和PostgreSQL 和Hibernate搜索(5.7.0.Alpha1) 使用ElasticSearch(2.4.2)。

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

我注释Book这样的课程:

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

我读过这样的情况,我需要在@ContainedIn侧使用Author注释, 所以我做了。出于这个原因,我需要添加属性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的行为, 所以书籍文件仍未更新。 你能给我一些关于我能做什么或检查的提示吗?

1 个答案:

答案 0 :(得分:1)

  

我使用Hibernate与PostgreSQL和Hibernate Search(5.7.0.Alpha1)与ElasticSearch(2.4.2)。

要做的第一件事就是升级到Hibernate Search的实际版本(不是Alpha版或Beta版),以确保您没有遇到自那时起已经解决的错误。

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