Semantic Search in Java with Micronaut Data JDBC, Oracle AI Vector Search and Database 26ai
Your users don’t always search with the same words your documents use.
Semantic search helps you find related content by meaning, not just matching keywords. Let’s explore how Java, Micronaut Data JDBC, and Oracle AI Vector Search in Oracle Database 26ai fit together, based on a demo by Oracle developer evangelist Juarez Barbosa Junior.
From Matching Words to Finding Meaning #
Imagine a support database containing these issues:
- “My laptop takes forever to start.”
- “The computer is slow after login.”
- “The monitor keeps flickering.”
The first two describe related problems, even though their wording differs. Semantic search can recognize that relationship using embeddings: numerical representations of content produced by an embedding model.
As Juarez explains:
You can store and query vector embeddings directly in our Oracle AI Database 26ai.
The basic workflow is straightforward:
- Prepare your content. Split long documents into smaller sections, called chunks.
- Generate embeddings. Use an embedding model to convert each chunk into a vector.
- Store the vectors. Save them alongside the source text and useful metadata.
- Embed the search query. Use the same model and compatible settings.
- Find nearby vectors. Return the content most similar to the query.
You don’t need a chatbot to benefit from this. Better document search or support-ticket matching is already a useful starting point.
How the Java Stack Fits Together #
Each part of the stack has a clear responsibility:
- Micronaut handles the application, configuration, and HTTP endpoints.
- Micronaut Data JDBC provides repositories for database access.
- Oracle JDBC connects the Java application to the database.
- Oracle AI Vector Search stores vectors and performs similarity searches.
The demo follows a familiar structure: a controller receives a request, a service coordinates the work, and a repository queries the database.
Micronaut Data generates repository implementations and derived queries at compile time. You can also define custom SQL with @Query when you need more control. Database execution still happens at runtime, so integration tests remain essential.
The practical advantage? You can keep relational data and vectors in one database, rather than introducing a separate vector store immediately.
Get Dimensions and Distance Metrics Right #
Before writing search logic, check your embedding mode’s documentation.
Juarez highlights this configuration detail:
Some models support many different dimensions. Some models support just one.
The vector column’s dimensions must match the embeddings you generate. Also, matching dimensions alone isn’t enough: vectors from different models generally aren’t directly comparable.
Next, choose a distance metric appropriate for your model:
- Cosine distance compares vector direction.
- Euclidean distance measures straight-line distance between vectors.
- Dot product compares vectors using both direction and magnitude.
The presentation’s vector diagram makes cosine comparison easier to understand: arrows pointing in similar directions are similar, even when their lengths differ. It’s a useful visual explanation, though real embeddings usually have far more dimensions than a diagram can show.
Don’t reuse thresholds blindly across metrics. Their scales and meanings differ. A cutoff that returns useful results with one metric may return nothing with another.
Build a Small, Inspectable Search Demo #
Juarez’s dashboard starts with six documents and lets users compare searches, result counts, and scoring functions. That’s a good development approach: make search behavior visible before scaling it.
Try this:
- Run Oracle AI Database Free locally, using a supported container setup.
- Create a Micronaut application with Data JDBC and Oracle connectivity.
- Keep credentials outside source code, using environment variables or a secrets manager.
- Load a small, representative dataset, including related and unrelated documents.
- Show results with their scores and source text. Label whether higher or lower scores indicate a better match.
- Test realistic questions, including paraphrases and queries with no relevant answer.
Start with relevance testing. As the dataset grows, evaluate vector indexes and measure their effect on latency and retrieval quality.
Later, you can feed retrieved passages into a language model. That’s retrieval-augmented generation, or RAG: supplying relevant context to help the model answer. Retrieval supports better answers; it doesn’t guarantee correctness.
Start Small, Then Expand #
Semantic search becomes easier to build when you separate embedding generation, storage, and retrieval. Micronaut Data JDBC gives you a familiar Java structure, while Oracle Database 26ai keeps vectors close to your application data. Start with a small dataset, verify dimensions and scoring behavior, and inspect the results before adding indexes or a RAG workflow.