LangChain Java Integration
Use LangChain4j with Oracle AI Database to store embeddings and run vector search from Java applications.
LangChain4j provides OracleEmbeddingStore, an embedding store that integrates with Oracle Database AI Vector Search. Use it to persist text segments, embeddings, and metadata in Oracle AI Database.
Contents
- Add the Maven Dependency
- Configure a Data Source
- Use an Existing Embedding Table
- Create an Embedding Table
- Customize Table Columns
- Create an IVF Vector Index
- Create a JSON Metadata Index
- Use the Embedding Store in Retrieval Workflows
- Review Reference Links
Add the Maven Dependency
Add the LangChain4j Oracle module to your Maven build.
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-oracle</artifactId>
<version>1.16.2-beta26</version>
</dependency>
Use the version that matches the rest of your LangChain4j dependencies.
Configure a Data Source
OracleEmbeddingStore requires a Java DataSource and an embedding table configuration. Use a pooled data source, such as Oracle Universal Connection Pool or HikariCP, for production applications.
DataSource dataSource = myDataSource;
Connection pooling avoids the latency of opening a new database connection for each embedding store operation.
Use an Existing Embedding Table
If the embedding table already exists, pass the table name to the builder.
EmbeddingStore<TextSegment> embeddingStore = OracleEmbeddingStore.builder()
.dataSource(dataSource)
.embeddingTable("my_embedding_table")
.build();
By default, LangChain4j expects the embedding table to use the following columns.
| Column | Type | Description |
|---|---|---|
id |
VARCHAR(36) |
Primary key that stores generated UUID strings. |
embedding |
VECTOR(*, FLOAT32) |
Embedding vector. |
text |
CLOB |
Text segment content. |
metadata |
JSON |
Text segment metadata. |
Create an Embedding Table
If the table does not exist, pass a create option to the embedding table configuration.
EmbeddingStore<TextSegment> embeddingStore = OracleEmbeddingStore.builder()
.dataSource(dataSource)
.embeddingTable("my_embedding_table", CreateOption.CREATE_IF_NOT_EXISTS)
.build();
Use CREATE_IF_NOT_EXISTS for application startup flows that should create the table only when it is missing.
Caution: Use replacement create options only in development or controlled rebuild workflows because they can remove existing embedding data.
Customize Table Columns
Use EmbeddingTable.builder() when your table uses custom names for the table or columns.
OracleEmbeddingStore embeddingStore = OracleEmbeddingStore.builder()
.dataSource(dataSource)
.embeddingTable(
EmbeddingTable.builder()
.createOption(CreateOption.CREATE_OR_REPLACE)
.name("my_embedding_table")
.idColumn("id_column_name")
.embeddingColumn("embedding_column_name")
.textColumn("text_column_name")
.metadataColumn("metadata_column_name")
.build()
)
.build();
Use CreateOption.NONE when the table already exists and you want LangChain4j to use it without creating or replacing it.
Create an IVF Vector Index
Use an IVF index on the embedding column when approximate vector search is appropriate for your workload.
OracleEmbeddingStore embeddingStore = OracleEmbeddingStore.builder()
.dataSource(dataSource)
.embeddingTable(
EmbeddingTable.builder()
.createOption(CreateOption.CREATE_OR_REPLACE)
.name("my_embedding_table")
.idColumn("id_column_name")
.embeddingColumn("embedding_column_name")
.textColumn("text_column_name")
.metadataColumn("metadata_column_name")
.build()
)
.index(
Index.ivfIndexBuilder()
.createOption(CreateOption.CREATE_OR_REPLACE)
.build()
)
.build();
IVF, or Inverted File Flat, indexes can improve vector search performance for large embedding tables.
Create a JSON Metadata Index
Use a JSON metadata index when retrieval filters target specific metadata keys.
OracleEmbeddingStore embeddingStore = OracleEmbeddingStore.builder()
.dataSource(dataSource)
.embeddingTable(
EmbeddingTable.builder()
.createOption(CreateOption.CREATE_OR_REPLACE)
.name("my_embedding_table")
.idColumn("id_column_name")
.embeddingColumn("embedding_column_name")
.textColumn("text_column_name")
.metadataColumn("metadata_column_name")
.build()
)
.index(
Index.jsonIndexBuilder()
.createOption(CreateOption.CREATE_OR_REPLACE)
.key("name", String.class, JSONIndexBuilder.Order.ASC)
.key("year", Integer.class, JSONIndexBuilder.Order.DESC)
.build()
)
.build();
The JSON index is a function-based index over selected keys in the metadata column.
Use the Embedding Store in Retrieval Workflows
Use OracleEmbeddingStore anywhere LangChain4j expects an EmbeddingStore<TextSegment>. A typical retrieval workflow follows this sequence:
- Create or configure a pooled
DataSource. - Build an
OracleEmbeddingStore. - Generate embeddings with a LangChain4j embedding model.
- Add text segments, embeddings, and metadata to the store.
- Query the store by vector similarity.
- Pass retrieved text segments to a chat model as grounding context.
The Oracle embedding store uses cosine similarity to calculate the distance between vectors.
Review Reference Links
- LangChain4j Oracle embedding store documentation: Source reference for
OracleEmbeddingStore. - LangChain4j Oracle module README: Source repository for the LangChain4j Oracle module.
- LangChain4j examples: Example applications for LangChain4j.
- Oracle AI Vector Search documentation: Oracle vector search concepts, SQL functions, and indexing.