Persistence Layout

We use JPA for the persistence. There are 2 types of classes that get persisted: domain classes and facet classes

Domain Classes

These are the classes from the com.fluxtream.domain packages. They cover things like users (Guest), user settings (GuestSettings), API keys (ApiKey) and notifications (Notification), etc.

Facet Classes

Connector data is cached on the database using JPA classes that we call Facets. 

AbstractFacet

The base class for all facets is in the domain package, AbstractFacet, which thus defines some attributes that are common to all facets:

@Field(index=org.hibernate.search.annotations.Index.UN_TOKENIZED, store=Store.YES)
@Index(name="start_index")
public long start;
@Index(name="end_index")
public long end;
@Index(name="api_index")
public int api;
@Index(name="objectType_index")
public int objectType;
@Lob
@Field(index=org.hibernate.search.annotations.Index.TOKENIZED, store=Store.YES)
public String comment;
@Field(index=org.hibernate.search.annotations.Index.TOKENIZED, store=Store.YES)
@Lob
public String fullTextDescription;
Looking at this code, we can see that we are able to filter facets using a guestId, `api` and objectType index, as well as start and end timestamps. We also provide a special field that will be used by Lucene's indexer to enable full-text search of the specific type of facet.
Specialized Facet Classes

The specialized Facet classes are to be found in the individual connector packages in the connectors module, e.g. Twitter's Direct Message Facet (TwitterDirectMessageFacet) is defined in the com.fluxtream.connectors.fitbit package:

@Indexed
public class TwitterDirectMessageFacet extends AbstractFacet {
public long twitterId;
public String text;
long time;
@Index(name="sent_index")
byte sent;
public String recipientName;
public String senderName;
public String recipientScreenName;
public String senderScreenName;
public String senderProfileImageUrl;
public String recipientProfileImageUrl;
@Override
protected void makeFullTextIndexable() {
this.fullTextDescription = senderName + " " + senderScreenName + " " + text;
 }
}
One table per Facet type

Since we are using the hibernate implementation of JPA, we found that we didn't want to rely on too complex inheritance mapping that could lead to performance problems that are typically very difficult to debug.