我使用Hibernate和PostgreSQL 和Hibernate Search(5.7.0.Alpha1
) 和ElasticSearch(2.4.2
)。如何在Hibernate Search中正確使用@ContainedIn註解?
我有兩個類:Book
和Author
。 一本書可以有許多作者 ,作者可以創作多本書。
我註解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的行爲, 所以書文件還沒有更新。 你能提供一些關於我可以做什麼或檢查的提示嗎?
非常感謝您的幫助,它解決了我的問題。我不是發佈'author01.addBook(book01)',而是從數據庫中強制更新'author01'對象(我還添加了'cascade'和'fetch'註釋),因爲我認爲這對我來說是一個更現實的設置。更新後'author01'在其列表中包含'book01',然後'@ ContainedIn'工作 - 圖書文檔在ElasticSearch中得到更新。謝謝! – nuoritoveri
@nuoritoveri - 在你的問題中,你寫道:「爲此,我需要添加屬性authoredBooks」。 YoannRodière的解決方案是作爲獨立解決方案工作的,還是您提及的財產加上ContainedIn註釋也是解決方案的關鍵部分? – Hervian
我不得不用'@ ContainedIn'添加'authoredBooks',然後觸發對象的更新,所以這兩個元素都是必需的。 – nuoritoveri