2017-07-20 62 views
2

我使用Hibernate和PostgreSQL 和Hibernate Search(5.7.0.Alpha1) 和ElasticSearch(2.4.2)。如何在Hibernate Search中正確使用@ContainedIn註解?

我有兩個類: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"}]}}} 

我讀到了類似的情況我需要在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的行爲, 所以書文件還沒有更新。 你能提供一些關於我可以做什麼或檢查的提示嗎?

回答

1

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

要做的第一件事就是升級到Hibernate Search的實際版本(不是Alpha或Beta),以確保您沒有遇到自此以後解決的錯誤。

除此之外......你的初始代碼只更新關係的一側;您是否確定在ook01.addAuthor(author01)之後添加author01.addBook(book01)行?

+0

非常感謝您的幫助,它解決了我的問題。我不是發佈'author01.addBook(book01)',而是從數據庫中強制更新'author01'對象(我還添加了'cascade'和'fetch'註釋),因爲我認爲這對我來說是一個更現實的設置。更新後'author01'在其列表中包含'book01',然後'@ ContainedIn'工作 - 圖書文檔在ElasticSearch中得到更新。謝謝! – nuoritoveri

+0

@nuoritoveri - 在你的問題中,你寫道:「爲此,我需要添加屬性authoredBooks」。 YoannRodière的解決方案是作爲獨立解決方案工作的,還是您提及的財產加上ContainedIn註釋也是解決方案的關鍵部分? – Hervian

+0

我不得不用'@ ContainedIn'添加'authoredBooks',然後觸發對象的更新,所以這兩個元素都是必需的。 – nuoritoveri