DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Architectural Miscalculation and Hibernate Problem "Type UUID but Expression Is of Type Bytea"
  • How to Store Text in PostgreSQL: Tips, Tricks, and Traps
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive
  • The Ultimate Guide on DB-Generated IDs in JPA Entities

Trending

  • Five Free AI Tools for Programmers to 10X Their Productivity
  • Extracting Maximum Value From Logs
  • SAP Business One vs. NetSuite: Comparison and Contrast of ERP Platforms
  • A Complete Guide to Open-Source LLMs
  1. DZone
  2. Data Engineering
  3. Databases
  4. Hibernate Search : Mapping Entities

Hibernate Search : Mapping Entities

Meera Subbarao user avatar by
Meera Subbarao
·
Nov. 18, 08 · Interview
Like (0)
Save
Tweet
Share
26.64K Views

Join the DZone community and get the full member experience.

Join For Free

 All Hibernate Search mapping metadata is described through annotations. Hibernate Search metadata is very code centric and shares a lot of information from the class structure: annotations are a natural fit and avoid lots of redundancy compared to other metadata models like XML. It would be quite simple to add an XML deployment descriptor support for Hibernate Search. Nobody has found the time and interest to write this layer (so far) which seems to prove that this feature is not that strongly desired by the Hibernate Search community.

All Hibernate Search annotations are contained in the org.hibernate.search.annotations package.

 To mark an entity as indexed by Hibernate Search, just place the @Indexed annotation on the class.

Listing 1 An entity is indexed by Hibernate Search when marked @Indexed

@Entity
@Indexed
public class Dvd {
...
}

 A lot of information is inferred and a lot of work is triggered from this single annotation. When the Hibernate SessionFactory bootstraps, Hibernate Search looks for all mapped entities marked as @Indexed and processes them.
The benefit for us is that we do not have to explicitly list the indexed entities in a configuration file: it both reduces our work and limits the risk of mistakes.

The Lucene directory name is also inferred from this annotation. Because we have not explicitly defined an index name, the default naming applies. The index name is the fully qualified class name of the entity: in our example com.manning.hsia.dvdstore.model.Dvd. You can override this name by using the name attribute of @Indexed.


Listing 2 An indexed entity overriding its index name to refine the targeted Lucene Directory

@Entity
@Indexed(name="Item")
public class Dvd {
...
}

The underlying mapping between a Hibernate Search index name and a physical Lucene Directory depends entirely on the directory provider. Let's explore the two most common scenarios: the in memory directory provider (RamDirectoryProvider) and the file system directory provider (FSDirectroyProvider).
Indexes using the RamDirectoryProvider are uniquely identified by their index name for a given SessionFactory (or EntityManagerFactory if you use Java Persistence). Said otherwise, Hibernate Search keeps an instance of RamDirectory per index name when the index targets the RamDirectoryProvider.
When using FSDirectoryProvider, the index name represents the path to the physical file system directory. Relative path are prefixed with the indexBase property.


It is perfectly safe to share the same physical Lucene directory for several entities: Hibernate Search does partition the information. If you want to share the same physical Lucene directory across several entities, they just need to share the same @Indexed.name value (as well as the same DirectoryProvider type).

Listing 3 Indexed entity sharing the same underlying Lucene directory

 

@Entity
@Indexed(name="Item") The same index name is shared by both entities
public class Dvd {
...
}
@Entity
@Indexed(name="Item")
public class Drink {
...
}

 

Should I share the same Lucene directory for all my entities?
Usually, this is not necessary.
Sharing the same index will help to optimize queries as Hibernate Search will have to handle less resources at the same time. This is particularly true when the amount of index data is low. On the other hand, when the amount of data starts to grow significantly, splitting the index into several ones will help Lucene to grow. Hibernate Search offers such a possibility through what is called index sharding.
The gain provided by sharing the directory is usually not significant enough to make a difference. Maintenance might be a stronger criterion but you can see the glass half full or half empty:
•
Having one index per entity helps maintainability and allows incremental rebuild if something goes wrong on an index file
•
But having one single index (arguably) reduces maintenance
As you can see, there is no clear winner and Hibernate Search let's you do what you prefer. The authors tend to use the Hibernate Search defaults and let it mind its own business. Ease of development is really where the gain

Entity structure can be more complex than the previous example, especially when subclasses are involved.

Subclasses:

Hibernate Search, just like Hibernate is fully polymorphic and let you map hierarchies of classes as well as express polymorphic queries. Practically for you, it means that you can write classes and subclasses in your domain model without worrying about Hibernate Search. Back to your store example, our client forgot to tell us that on top of DVDs, the website also has to sell food such as popcorns and drinks such as wines. (I don't know about popcorn, but chilling out with a glass of decent wine in front of a good movie is definitely something I would be ready to pay for). We will refactor our domain model to cope with this new requirement. The website will see Items that will be declined in Dvds, Food and Drinks.

Listing 4 Mapping a class and its subclass

 Hibernate Search will not only index the marked properties of a given class but also all the marked property of its superclass. In Listing 4, the Drink entity will be searchable by the following properties:

  • alcoholicBeverage from Drink
  • id from Item
  • title from Item

You might have noticed that the Item entity is not marked as @Indexed. While marking Item with @Indexed will do no harm, it is simply not necessary. You should only mark entities with @Indexed when:

  • You want to be able to search by this entity
  • And the entity is of a concrete type (not abstract).

In our system, Item is an abstract class and hence will have no instances of it. Subclasses are denormalized in the Lucene index: all instances of Drink will be stored in the org.manning.hsia.dvdstore.model.Drink index including the information about its superclass' properties id and title.

Denormalization does not prevent you from executing polymorphic queries. As we will see later in this book, you can perfectly search for all Items whose title contains “valley”. Both the DVD “In the Valley of Elah” and “Nappa valley” wines will show up even if Item has not been marked with @Indexed.

 Hibernate Search does not read metadata annotations from interfaces but you can of course map the implementation class and its properties.

This article is based on chapter 3 from Hibernate Search in Action by Emmanuel Bernard and John Griffin. It is being reproduced here by permission from Manning Publications.

Manning early access books and ebooks are sold exclusively through Manning. 
Visit the book's page for more information.
Database Hibernate

Opinions expressed by DZone contributors are their own.

Related

  • Architectural Miscalculation and Hibernate Problem "Type UUID but Expression Is of Type Bytea"
  • How to Store Text in PostgreSQL: Tips, Tricks, and Traps
  • Simplify Java Persistence Using Quarkus and Hibernate Reactive
  • The Ultimate Guide on DB-Generated IDs in JPA Entities

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: