You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
An ultra-light-weight HBase ORM library that enables:
9
+
HBase ORM is a light-weight, thread-safe and performant library that enables:
10
10
11
11
1. object-oriented access of HBase rows (Data Access Object) with minimal code and good testability
12
12
2. reading from and/or writing to HBase tables in Hadoop MapReduce jobs
13
13
14
-
15
14
## Usage
16
15
Let's say you've an HBase table `citizens` with row-key format of `country_code#UID`. Now, let's say this table is created with three column families `main`, `optional` and `tracked`, which may have columns (qualifiers) `uid`, `name`, `salary` etc.
17
16
@@ -115,14 +114,15 @@ See source files [Citizen.java](./src/test/java/com/flipkart/hbaseobjectmapper/t
115
114
116
115
### Serialization / Deserialization mechanism
117
116
117
+
* Serialization and deserialization are handled through 'codecs'.
118
118
* The default codec (called [BestSuitCodec](./src/main/java/com/flipkart/hbaseobjectmapper/codec/BestSuitCodec.java)) included in this library has the following behavior:
119
119
* uses HBase's native methods to serialize objects of data types `Boolean`, `Short`, `Integer`, `Long`, `Float`, `Double`, `String` and `BigDecimal` (see: [Bytes](https://hbase.apache.org/2.0/devapidocs/org/apache/hadoop/hbase/util/Bytes.html))
120
120
* uses [Jackson's JSON serializer](https://en.wikipedia.org/wiki/Jackson_(API)) for all other data types
121
121
* serializes `null` as `null`
122
122
* To customize serialization/deserialization behavior, you may define your own codec (by implementing the [Codec](./src/main/java/com/flipkart/hbaseobjectmapper/codec/Codec.java) interface) or you may extend the default codec.
123
123
* The optional parameter `codecFlags` (supported by both `@HBColumn` and `@HBColumnMultiVersion` annotations) can be used to pass custom flags to the underlying codec. (e.g. You may want your codec to serialize field `Integer id` in `Citizen` class differently from field `Integer id` in `Employee` class)
124
124
* The default codec class `BestSuitCodec` takes a flag `BestSuitCodec.SERIALIZE_AS_STRING`, whose value is "serializeAsString" (as in the above `Citizen` class example). When this flag is set to `true` on a field, the default codec serializes that field (even numerical fields) as strings.
125
-
* Your custom codec may take other such flags to customize serialization/deserialization behavior at a **class field level**.
125
+
* Your custom codec may take other such flags as inputs to customize serialization/deserialization behavior at a **class field level**.
126
126
127
127
## Using this library for database access (DAO)
128
128
This library provides an abstract class to define your own [data access object](https://en.wikipedia.org/wiki/Data_access_object). For example, you can create one for `Citizen` class in the above example as follows:
Note that **all** of the above are very heavy and time-consuming operations.
318
+
Note that DDL operations on HBase are typically heavy and time-consuming.
319
319
320
320
## Using this library in MapReduce jobs
321
321
@@ -325,6 +325,7 @@ If your MapReduce job is reading from an HBase table, in your `map()` method, HB
325
325
```java
326
326
T readValue(ImmutableBytesWritable rowKey, Result result, Class<T> clazz)
327
327
```
328
+
where `T` is your bean-like class that extends this library's `HBRecord` interface (e.g. `Citizen` class above).
328
329
329
330
For example:
330
331
@@ -336,11 +337,13 @@ Citizen e = hbObjectMapper.readValue(key, value, Citizen.class);
336
337
If your MapReduce job is writing to an HBase table, in your `reduce()` method, object of your bean-like class can be converted to HBase's `Put` (for row contents) and `ImmutableBytesWritable` (for row key) using below methods:
337
338
338
339
```java
339
-
ImmutableBytesWritable getRowKey(HBRecord<R> obj)
340
+
ImmutableBytesWritable getRowKey(T record)
340
341
```
341
342
```java
342
-
Put writeValueAsPut(HBRecord<R> obj)
343
+
Put writeValueAsPut(T record)
343
344
```
345
+
where `T` is your bean-like class that extends this library's `HBRecord` interface (e.g. `Citizen` class above).
346
+
344
347
For example, below code in Reducer writes your object as one HBase row with appropriate column families and columns:
345
348
346
349
```java
@@ -353,11 +356,13 @@ If your MapReduce job is reading from an HBase table, you would want to unit-tes
353
356
Object of your bean-like class can be converted to HBase's `Result` (for row contents) and `ImmutableBytesWritable` (for row key) using below methods:
354
357
355
358
```java
356
-
ImmutableBytesWritable getRowKey(HBRecord<R> obj)
359
+
ImmutableBytesWritable getRowKey(T record)
357
360
```
358
361
```java
359
-
Result writeValueAsResult(HBRecord<R> obj)
362
+
Result writeValueAsResult(T record)
360
363
```
364
+
where `T` is your bean-like class that extends this library's `HBRecord` interface (e.g. `Citizen` class above).
365
+
361
366
Below is an example of unit-test of a Mapper using [MRUnit](https://attic.apache.org/projects/mrunit.html):
362
367
363
368
```java
@@ -382,6 +387,8 @@ HBase's `Put` object can be converted to your object of you bean-like class usin
382
387
```java
383
388
T readValue(ImmutableBytesWritable rowKey, Put put, Class<T> clazz)
384
389
```
390
+
where `T` is your bean-like class that extends this library's `HBRecord` interface (e.g. `Citizen` class above).
391
+
385
392
386
393
Below is an example of unit-test of a Reducer using [MRUnit](https://attic.apache.org/projects/mrunit.html):
* Your application code will be clean and minimal.
408
+
* Your application code will be **clean** and **minimal**.
402
409
* Your code need not worry about HBase methods or serialization/deserialization at all, thereby helping you maintain clear [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns).
403
-
* Classes are **thread-safe**. You just have to instantiate your DAO classes once at the start of your application and use them anywhere!
404
-
* Light weight: This library depends on just HBase Client and few other small libraries. It has very low overhead and hence is very fast.
405
-
* Customizability/Extensibility: Want to use HBase native methods directly in some cases? No problem. Want to customize ser/deser in general or for a given class field? No problem. This library is high flexible.
410
+
* Classes are **thread-safe**. You just have to instantiate your DAO classes once at the start of your application and use them anywhere throughout the life-cycle of your application!
411
+
***Light weight**: This library depends on just [hbase-client](https://mvnrepository.com/artifact/org.apache.hbase/hbase-client) and few other small libraries. It has very low overhead and hence is very fast.
412
+
* Customizability/Extensibility: Want to use HBase's native methods directly in some cases? You can do that. Want to customize serializatoin/deserialization for a given type or for a specific given class field? You can do that too. This library is highly flexible.
406
413
407
414
## Limitations
408
415
Being an *object mapper*, this library works for pre-defined columns only. For example, this library doesn't provide ways to fetch:
@@ -417,7 +424,7 @@ Add below entry within the `dependencies` section of your `pom.xml`:
417
424
<dependency>
418
425
<groupId>com.flipkart</groupId>
419
426
<artifactId>hbase-object-mapper</artifactId>
420
-
<version>1.15</version>
427
+
<version>1.16</version>
421
428
</dependency>
422
429
```
423
430
@@ -428,7 +435,7 @@ See artifact details: [com.flipkart:hbase-object-mapper on **Maven Central**](ht
428
435
To build this project, follow below simple steps:
429
436
430
437
1. Do a `git clone` of this repository
431
-
2. Checkout latest stable version `git checkout v1.15`
438
+
2. Checkout latest stable version `git checkout v1.16`
@@ -588,8 +585,8 @@ public Append getAppend(R rowKey) {
588
585
* Performs HBase's {@link Table#append} on the given {@link Append} object <br>
589
586
* <br>
590
587
* <b>Note</b>: <ul>
591
-
* <li>You may construct {@link Append} object using the {@link #getAppend(Serializable) getAppend} method</li>
592
-
* <li>Unlike the {@link #append(Serializable, String, Object)} and related methods, this method skips some validations. So, use this only if you need access to HBase's native methods.</li>
588
+
* <li>You may construct {@link Append} object using the {@link #getAppend(Serializable) getAppend(R)} method</li>
589
+
* <li>Unlike the {@link #append(Serializable, String, Object) append(R, String, Object)} and related methods, this method skips some validations. So, use this only if you need access to HBase's native methods.</li>
593
590
* </ul>
594
591
*
595
592
* @param append HBase's {@link Append} object
@@ -622,7 +619,7 @@ public List<T> get(R startRowKey, R endRowKey) throws IOException {
622
619
* @return Row key of the persisted object, represented as a {@link String}
@@ -851,7 +848,7 @@ public NavigableMap<R, NavigableMap<Long, Object>> fetchFieldValues(R startRowKe
851
848
}
852
849
853
850
/**
854
-
* Fetch column values for a given array of row keys (bulk variant of method {@link #fetchFieldValue(Serializable, String)})
851
+
* Fetch column values for a given array of row keys (bulk variant of method {@link #fetchFieldValue(Serializable, String) fetchFieldValue(R, String)})
855
852
*
856
853
* @param rowKeys Array of row keys to fetch
857
854
* @param fieldName Name of the private variable of your bean-like object (of a class that implements {@link HBRecord}) whose corresponding column needs to be fetched
@@ -882,7 +879,7 @@ public Map<R, NavigableMap<Long, Object>> fetchFieldValues(R[] rowKeys, String f
0 commit comments