我有一个名为 Book 的课程,其中包含2个字段, id 和 isbn 。 我想使用 id 字段作为主键执行正常的Hibernate查询,同时使用 isbn 字段作为主键执行Hibernate Search查询。
所以我将 @Id 注释放在 id 字段上, @DocumentId 注释放在 isbn 上领域,如下。
@Entity
@Indexed
public class Book {
@Id
private Long id;
@DocumentId(name = "_documentId")
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private Long isbn;
...
}
然后我发现,在Hibernate Search索引编制过程开始后,虽然 Book 实体的所有新更新都已正确编入索引,但数据库中现有的 Book 实体是没有索引。
将 @DocumentId 注释从 isbn 字段移至 id 字段后,如下所示,现有图书当Hibernate Search索引过程开始时,数据库中的实体将再次编入索引。
@Entity
@Indexed
public class Book {
@Id
@DocumentId(name = "_documentId")
private Long id;
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private Long isbn;
...
}
所以我的问题是 即使@DocumentId和@Id注释位于不同的字段上,Hibernate Search索引过程是否也能像以前一样工作?。
我使用Luke检查Hibernate Search索引。
Book.java
@Entity
@Indexed
public class Book {
@Id
private Long id;
@DocumentId(name = "_documentId")
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private Long isbn;
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private int version;
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
private String content;
public Book() {
}
public Book(Long isbn, int version, String content) {
this.isbn = isbn;
this.version = version;
this.content = content;
}
@Override
public String toString() {
return "Book [id=" + id + ", isbn=" + isbn + ", version=" + version + ", content=" + content + "]";
}
// Getters and setters...
}
Book.hbm.xml
<hibernate-mapping package="com.raychen518.study.hibernate">
<class name="Book" table="BOOKS">
<id name="id" column="ID">
<generator class="increment" />
</id>
<property name="isbn" column="ISBN" />
<property name="version" column="VERSION" />
<property name="content" column="CONTENT" />
</class>
</hibernate-mapping>
hibernate.cfg.xml中
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">org.postgresql.Driver</property>
<property name="connection.url">jdbc:postgresql://localhost:5432/test</property>
<property name="connection.username">postgres</property>
<property name="connection.password">admin</property>
<property name="connection.pool_size">1</property>
<property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">validate</property>
<property name="hibernate.search.lucene_version">LUCENE_CURRENT</property>
<property name="hibernate.search.default.directory_provider">filesystem</property>
<property name="hibernate.search.default.indexBase">hibernate.search.test/lucene/indexes</property>
<mapping resource="Book.hbm.xml" />
</session-factory>
</hibernate-configuration>
BookManager.java
在课程中执行 main(String [])方法后, isbn 字段的 Book 实体 789 将在索引中创建,而现有的图书实体(在数据库中) isbn 字段 123 < / strong>和 456 分别未编入索引。
public class BookManager {
public static void main(String[] args) throws InterruptedException {
BookManager manager = new BookManager();
manager.startIndexing();
manager.saveSome();
}
private void startIndexing() throws InterruptedException {
FullTextSession fullTextSession = Search.getFullTextSession(HibernateUtil.getSessionFactory().openSession());
fullTextSession.createIndexer(Book.class).startAndWait();
}
public void saveSome() {
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
// session.save(new Book(123L, 1, "abc"));
// session.save(new Book(456L, 1, "def"));
session.save(new Book(789L, 1, "ghi"));
session.getTransaction().commit();
session.close();
}
}
HibernateUtil.java
public class HibernateUtil {
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
return new MetadataSources(registry).buildMetadata().buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}