Skip to content

Migration guide: Java and Thrift clients

Documentation home · HappyBase migration · API reference

The driver uses native HBase RPC but is not a complete Java Client implementation. Familiar operation names do not guarantee identical defaults, result models, retry logic, or thread safety.

Start with a capability inventory

Before replacing a client, list the operations your application actually relies on:

  • data reads/writes, scan boundaries, and column projections;
  • cell timestamps, historical versions, and retention policies;
  • counters, conditional operations, and cross-row assumptions;
  • concurrent use, connection ownership, failover, and authentication;
  • snapshots, administrative procedures, and recovery requirements.

Compare each requirement with current limitations. If a critical feature is not implemented end-to-end, keep that path on the existing client until there is a tested solution.

Java-style concepts, Python-specific calls

Concept Current Python interface Migration caution
Configuration / connection Client(dict) Only implemented settings apply
Table identifier TableName.value_of(namespace, qualifier) Two byte-string arguments
Column-family descriptor ColumnFamilyDescriptorBuilder(...).build() Returns a protobuf schema
Put / Get / Delete Operation object passed to Table method Not every setter is chainable
Result Row or None No complete cells/timestamps/version-history model
ResultScanner with table.scan(scan) Explicit cleanup; no Java retry guarantee
Scan bounds with_start_row / with_end_row Both constructor bounds inclusive by default
BufferedMutator params Instantiate then assign attributes No constructor keyword parameters
Conditional mutation CheckAndPut or Table.check_and_delete Same-row condition; not a lock framework
Async admin procedure Returned procedure ID Must verify completion separately

Use bytes directly or encode application strings explicitly. Passing arbitrary Java configuration keys into the dictionary does not implement their behavior.

Minimal target pattern

This example assumes an existing default:users table with cf:

import os

from hbasedriver.client.client import Client
from hbasedriver.hbase_constants import HConstants
from hbasedriver.operations.get import Get
from hbasedriver.operations.put import Put

config = {HConstants.ZOOKEEPER_QUORUM: os.getenv("HBASE_ZK", "127.0.0.1:2181")}
with Client(config) as client:
    with client.get_table(b"default", b"users") as table:
        table.put(Put(b"user:001").add_column(b"cf", b"name", b"Alice"))
        row = table.get(Get(b"user:001").add_column(b"cf", b"name"))
        name = None if row is None else row.get(b"cf", b"name")
        print(name)

Client construction performs discovery. ZooKeeper, Master, and advertised RegionServers must be reachable. A Thrift endpoint is not a ZooKeeper endpoint.

Differences requiring application changes

Read shape and timestamps

Row maps one value to each family/qualifier. Requesting multiple versions does not produce a Java-style list of cells; timestamp information is lost. Current Get/Scan time-range paths are incomplete. Do not silently degrade an audit/history application to latest-value reads.

Batch results and failure boundaries

BatchGet returns a dictionary, not a positional array. BatchPut returns status booleans on success and can raise after earlier writes. Batch and BufferedMutator currently execute individual calls. They do not provide cross-row atomicity or Java Multi-request throughput characteristics.

Scans and pagination

Specify end exclusivity explicitly. Do not pass Java-style or invented keywords to the constructor. Use next_batch(n) for bounded consumption, and use exclusive resume keys for pagination. Preserve all predicates and bounds between pages. Reverse/cross-region behavior under splits needs separate testing.

Concurrency, retry, and resource ownership

Do not transfer Java Connection/Table thread-sharing assumptions without tests. Current cleanup and shared caches have limitations. A timeout can leave the write outcome unknown. Replaying Increment/Append is not safe without deduplication or reconciliation.

Administration

Use unique test resources. Table truncation currently deletes/recreates and does not preserve splits/full metadata. Snapshot restore/clone returns a procedure ID, not completed data. Cluster-wide changes need operational approval and verification.

A staged validation plan

Stage Required evidence
Schema/encoding comparison Byte-for-byte agreement for known rows, empty values, and counters
Query comparison Correct first/last boundaries, filters, missing rows, and pagination
Write comparison Correct single-row results and tested conditional-failure path
Failure testing Known handling of timeouts, partial batches, reconnects, and Region movement
Performance test End-to-end completion time, latency distribution, errors, resource growth
Rollout Limited traffic, monitoring, rollback ownership, no unsafe duplicate writes

Start with the cookbook, then add application-specific integration tests. Documentation smoke tests are a foundation, not a migration acceptance test for every production workload.