1. FreshDbCache


If you want more advanced cache than entities sorted by id, implement your own FreshDbCache. You can rely on collections from java.util.concurrent. My favourite are ConcurrentHashMap (for non-orderes index) and ConcurrentSkipListMap (for ordered index). Concurrent collections are required, because this collections are being modified by cache manager while you use them in your controllers/services.

Check JavaDoc for detailed information and examples for reference implementation.



2. FreshDbCacheManager


There are some configuration parameters of cache manager that you can override.

dbChangesReadInterval - time in miliseconds how often cache manager requests database for new changes. Default 500.

changesReadInBatchCount - maximal count of changes, that are read and processed at once. Default 10000.

minChangesCountLeftInChangesTable - minimal count of changes that are not deleted from table of changes. Default 10000

changesLifetimeFormulaInChangesTable - SQL time interval condition for what is the minimal lifespan of changes in changes table. For postgresql you have to use "now() - 4:00:00" as it does not support subtime function. Default "subtime(now(),4:00:00)".



3. FreshDbEntity


Each entity class used by Fresh DB Cache must be annotated with this annotation. It has some very important mandatory parameters:

changesTableEntityIdentificator - Changes table is filled by triggers that you have to manually put into database. We use identification string to distinguish different entities in same changes table. Let's say that for Game entity we use identificator "game". This string must be then used in all 3 triggers as well as value for this annotation property. In other words this is string stored in entity_class column in changes table.

initializationSelect - Select that loads next X records of annotated entity (where X = initializationSelectLimit value).

During initialization phase all entities must be loaded from database to cache. Due to bigger tables we do this step by step every time asking next X (10 000) records. Last id of previous set is used as first id exclusive for next set. We repeat this unitl we get less records than requested meaning that we have loaded all entities.

Select must have 2 named parameters

1. :limit - maximal count of records loaded - will be replaced by initializationSelectLimit value. Less records can be returned only if there is no more records.

2. :idFrom - id from which next records will be read (exclusive). Will be replaced by FreshDbEntityId column of last loaded entity. For first select it's replaced by zeroId property of this annotation.

Values are replaced as strings and final select is run as not-prepared statement to allow to use of composite ids.

Example: SELECT id,game_number,game_name FROM games WHERE id > :idFrom ORDER BY id asc LIMIT :limit

multiIdSelect - After initialization fresh db cache reads changes table to get ids of added/updated/deleted entities. After getting ids we need to actually load those entities and that's where this select is used.
Select must have one named parameter - :idsList - it's placeholder where list of comma separated ids to be loaded will be inserted.
Example: SELECT id,game_number,game_name FROM games WHERE id IN (:idsList)

entityPrimaryKeyClass - This must match with key class defined in all caches as well as with getter result type of column annotated as id column. Default is Long. This class must implement static method valueOf(String val) that returns new instance of key class.
initializationSelectLimit - Number of records loaded in one select during initialization. Default is 10 000.

zeroId - String value that is used in first initialization select as primary key lower than lowest primary key. For standard long primary keys the value is -1. If you have some special primary key, specify your own value.



4. FreshDbEntityColumn


Every attribute that should be filled by Fresh DB Cache must be annotated with this annotation. Fresh DB Cache uses standard setter to set value. Annotation has folloeing attributes:

column - Name of column that should be mapped to this attribute

valueMappingClass - Class that sets column value to attribute. You can use your own class (implement ColumnValueMapper interface) if you want some special mapping or attribute class isn't supported by DefaultColumnValueMapper. For dates use DateColumnValueMapper.

valueMappingClassParameters - If value mapping class needs some parameters, put them here. Default is empty string.

isId - When set to true, this column is considered as id column and attribute as id attribute. For id there are some validations that will be done during cache manager initialization. Class of id attribute must match key class of all caches that handle this entity class and there must be exactly one attribute marked as id in entity class.



5. ColumnValueMapper


Interface that allows you to map from columns with non-standard values or map to attributes with non-standar classes.

Methods:

setParams - Parameters, that are defined in attribute annotation are passed to value mapper in this method during its initialization. It's upon you what parameters it will be (string can handle almost enything).

mapValue(Class attributeClass,String value) - Method that transforms String value from resultSet.getString(fieldName) into object that can will be passed to method setter. If value in database is null, null is provided also as value parameter.



6. DatabaseChangesLoader


DatabaseChangesLoader interface is quite rarely used extension point. If normal implementation (DatabaseChangesLoaderImpl) does not work with your database, you can fix it in own class and set it as FreshDbCacheManager property. For more info look at JavaDoc and DatabaseChangesLoaderImpl sources.