Hollow includes a few ready-made data ingestion mechanisms. Additionally, custom data ingestion mechanisms can be created relatively easily using the Low Level Input API.

HollowObjectMapper

The HollowObjectMapper will add POJOs into a HollowWriteStateEngine:

HollowWriteStateEngine engine = /// a state engine
HollowObjectMapper mapper = new HollowObjectMapper(writeEngine);

for(Movie movie : movies)
    writeEngine.add(movie);

The HollowObjectMapper can also be used to initialize the data model of a HollowWriteStateEngine without adding any actual data:

HollowWriteStateEngine engine = /// a state engine
HollowObjectMapper mapper = new HollowObjectMapper(writeEngine);

mapper.initializeTypeState(Movie.class);
mapper.initializeTypeState(Show.class);

The schemas will be assumed based on the field and type names in the POJOs. Any referenced types will also be traversed and included in the derived data model. The name of a type may be explicitly defined as something other than the class name using the @HollowTypeName annotation.

If an integer field named __assigned_ordinal is defined in POJOs, the HollowObjectMapper will use this field to memoize the assigned ordinal for instances. Upon addition of an object which already has this value memoized, the HollowObjectMapper will short-circuit retrieving the assigned ordinal. The field should be initialized to -1. The field may be, but does not have to be, private and/or final.

Warning

If the __assigned_ordinal optimization is used, and field values inside POJOs with this optimization are modified subsequent to their addition to a state engine, then the subsequent modifications will be ignored and any references to these POJOs will always point to the originally added record.

Additionally, if this optimization is used then POJOs should not be reused between cycles.

The following example Award class will reference a type AwardName, which will contain a single string value. The class will also employ the __assigned_ordinal shortcut:

public class Award {
    long id;

    @HollowTypeName(name="AwardName")
    String name;

    private final int __assigned_ordinal = -1;
}

Thread Safety

The HollowObjectMapper is thread-safe; multiple threads may add Objects at the same time.

JSON to Hollow Adapter

The project hollow-jsonadapter contains a component which will automatically parse json into a HollowWriteStateEngine. The expected format of the json will be defined by the schemas in the HollowWriteStateEngine. The data model must be pre-initialized. See the Schema Parser topic in this document for an easy way to configure the schemas with a text document.

The HollowJsonAdapter class is used to populate records of a single type from a json file. A single record:

{ 
  "id": 1,
  "releaseYear": 1999,
  "actors": [
     {
        "id": 101,
        "actorName": "Keanu Reeves"
     },
     {
        "id": 102,
        "actorName": "Laurence Fishburne"
     }
  ]
}

Can be parsed with the following code:

String json = /// the record above

HollowJsonAdapter jsonAdapter = new HollowJsonAdapter(writeEngine, "Movie");

jsonAdapter.processRecord(json);

If a field defined in the schema is not encountered in the json data, the value will be null in the corresponding Hollow record. If a field is encountered in the json data which is not defined in the schema, the field will be ignored.

A large number of records in a single file can also be processed:

Reader reader = /// a reader for the json file 

HollowJsonAdapter jsonAdapter = new HollowJsonAdapter(writeEngine, "Movie");

jsonAdapter.populate(reader);

When processing an entire file, it is expected that the file contains only a single json array of records of the expected type. The records will be processed in parallel.

Zeno to Hollow Adapter

The project hollow-zenoadapter has an adapter which can be used with Hollow’s predecessor, Zeno. We used this as part of our migration path from Zeno to Hollow, and it is provided for current users of Zeno who would like to migrate to Hollow as well. Start with the HollowStateEngineCreator.