Brightspot CMS Developer Guide


All data model classes extend from the com.psddev.dari.db.Record class in the Dari framework. All fields in a subclass of Record are persisted as a database record when the object is saved. In addition, Dari creates and saves an object type definition that contains the metadata of the model.

See also:

The following is a simple model of an article. It extends the Dari Record class and includes getter and setter methods for the headline, body, and leadImage fields. All fields in a Record object are persisted to the underlying database, with the exception of fields marked with the Java transient keyword.

import com.psddev.dari.db.*;

public class Article extends Record {

    @Required /* Annotation specifies that value is required for headline field */
    @Indexed  /* Annotation specifies that field is to be indexed */
    private String headline;

    private String body;

    private Image leadImage;

    public String getHeadline() {
        return headline;
    public void setHeadline(String headline) {
        this.headline = headline;

    public String getBody() {
        return body;
    public void setBody(String body) {
        this.body = body;

    public Image getLeadImage() {
        return leadImage;
    public void setLeadImage(Image leadImage) {
        this.leadImage = leadImage;


For each model created, Dari persists an object type definition, represented by an ObjectType class. An ObjectType defines the structure and the metadata of the model. This includes the core model class, such as Article in the above example, and any modifications, augmentations, or substitutions to the core model class. When a model is updated, the object type definition is updated.

The ObjectType#getInstance method returns an object type definition as a JSON object. For example, using the Code Editor, you can return the object type definition for the Article model class.

return ObjectType.getInstance(psddev.dari.test.Article.class);

The returned object is a comprehensive metadata listing that includes attributes about the model class, its fields, and its relationships to other classes. For example, the following JSON fragment for the Article model shows information about two of the model fields, headline and author. The headline field is declared in the core Article class. However, the author field is declared in ArticleModification (not shown), a modification that extends the Article class with a new field.

  "fields": [{
    "isRequired": true,
    "java.field": "headline",
    "java.declaringClass": "com.psddev.dari.test.Article"
    "isRequired": false,
    "java.field": "author",
    "java.declaringClass": "com.psddev.dari.test.ArticleModification"
  } ]

The next JSON fragment shows that there are indexes for two fields in the Article model: headline and body. The indexes are a result of the @Indexed annotations applied to these fields in the Article class.

  "indexes": [{
      "field": "headline",
      "fields": ["headline"],
      "type": "text",
      "isUnique": false,
      "caseSensitive": false,
      "visibility": false,
      "java.declaringClass": "com.psddev.dari.test.Article"
      "field": "body",
      "fields": ["body"],
      "type": "text",
      "isUnique": false,
      "caseSensitive": false,
      "visibility": false,
      "java.declaringClass": "com.psddev.dari.test.Article"

The object type definition also specifies other classes that contribute to the Article model. In addition to the modification class, an augmentation, ArticleAugmentation, is applied to the Article core class.

  "java.objectClass": "com.psddev.dari.test.Article",
  "java.modificationClasses": [
     "com.psddev.dari.test.Article", "com.psddev.dari.test.ArticleModification"
  "java.superClasses": [
    "com.psddev.dari.test.Article", "com.psddev.dari.db.Record", "java.lang.Object"
  "java.assignableClasses": [
    "com.psddev.dari.test.Article", "com.psddev.dari.db.Record", "java.beans.BeanInfo", "java.lang.Cloneable", "java.lang.Comparable", "com.psddev.dari.util.HtmlObject", "com.psddev.dari.db.Recordable", "java.lang.Object"
  "augmentationClassNamesByTargetClassName": {
    "com.psddev.dari.test.Downloadable": ["com.psddev.dari.test.ArticleAugmentation"]

ObjectType also contains methods for getting specific metadata items, such as fields, methods, and indexes.

A Record object is linked to state information that is also persisted to the database. A Record object’s state is represented by a State object that is retrievable from Record. Changes to either the Record or to the State object are copied to its associated object. Record and State include the same save methods, as Record delegates to State to execute those methods.

You can get a Record object’s state in one of the following ways:

State state = object.getState();
/* OR */

State provides numerous methods that return comprehensive information about a Record object. For example, there are methods to return an object’s metadata and instance data. The getStatus method returns com.psddev.dari.db.StateStatus, indicating if the object is deleted, reference-only, or saved. For Image or Video objects to which the @Recordable.PreviewField annotation is applied, the getPreview method returns the storage item that Brightspot uses to preview the object.

State includes methods to describe an object’s visibility. isVisible indicates if an object is hidden from queries for published objects. For hidden objects that implement Visibility labels, getVisibilityLabel returns the object’s current non-published state. (For additional information about how to exclude objects in queries, see Excluding records from queries with visibility labels.)

A State object reflects the state of the original Record object and any other objects that might subsequently be linked to the original object. Linked objects are modifications and augmentations. State provides methods to work with linked objects. The isInstantiableTo method indicates if an original object is linked to modifications or augmentations. If it is, the as method converts the state of an original object to an instance of a modification or augmentation. The linkObject and unLinkObject methods link and unlink related objects to the state of the Record object.

All subclasses of Record must have a nullary constructor. If you wish to have a constructor with arguments, you must also provide a nullary constructor.

Additionally, Record provides an afterCreate API which is called by the nullary constructor of the Record class. It does nothing by default, but you can override the method to perform operations which need to occur when objects are created.

Be advised that the nullary constructor (and therefore afterCreate) will be called every time the object is instantiated out of the database. If you want code to run only once, when an object is created for the first time, use the following pattern in a nullary constructor or the afterCreate method:

if (getState().isNew()) {
   /* One-time operations here */

Previous Topic
Data modeling
Next Topic
Was this topic helpful?
Thanks for your feedback.
The elements that get you up and running in a matter of days, from pre-built content types, to modules, to landing pages.

Content types
Landing pages
Everything you need to manage and administer content within Brightspot CMS, including plug-and-play integrations.

Authoring content
Admin configurations
A guide for installing, supporting and administering code on the Brightspot platform, including integrations requiring developer support to use.

Field types
Content modeling
Rich-text elements