Jello framework

Jello uses JDO as the underlying persistence framework to model relationships between persistent Entities. By following Jello guidelines for Relationship modeling as described below, you will also benefit from the complete REST representation support; including Deferred reference fetching, reference integrity validation, inline association count and Preview.

Unowned One-to-One Relationships

Calculated One-to-Many Relationships

Owned Relationships

Deferred Content

Deferred Content Preview

Inline Representation of Associated Entries

@Reference (jello.annotation.Reference)

Mark the field as a reference to a Jello instance. Field type must be either Key (recommended) or String.

Syntax:

@Reference(<JelloEntity class>) 

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public class Product extends JelloEntity {
   @Expose @KeyElement 
   public String serialNumber;
	
   @Expose @Reference(Category.class)
   public Key category;	
}

public class Category extends JelloEntity {
   @KeyElement public Integer id;	
}

Upon updating a reference field's value, Jello will validate the value to ensure Reference Integrity. That is, the reference instance exists and is of the same type as the reference declared type. For serialization simplicity, you might choose to define Reference fields as String but consider using reference fields of type Key over String to enable type validation and reference integrity check.


REST API

Read the Deferred Content section to learn how Jello handles references representation via REST API.

Reference Field metadata representation:

/jello/meta/demo/Product

{
   name: "demo.Product",
   ...
   fields: [
      {
         name: "category",
         type: "jello.Reference(demo.Category)"
      },
      ...
   }
   ...
}


Passing Reference Key type field value:

Jello uses the same URI notation used for Instance reference to pass Reference Key type fields' value as shown below. Use this notation both to set Reference fields' value or to pass reference Key as action parameter.

<entity path>(instance-id)

Example: Calling a method and passing a reference key parameter.

Deferred Content


Reference Key type field in query filter:

KEY:<entity path>(instance-id)

Add 'KEY:' prefix before the reference value as shown in the example below.

Deferred Content


@Association (jello.annotation.Association)

Define 1:N calculated association field. This is a not-persistent but rather a calculated field. Jello performs select query and returns association list just upon request.

Syntax:

@NotPersistent @Association(mappedBy="<field-name>", filteredBy="<query-select-expression>")

Jello will execute a select query based on the mappedBy and/or filteredBy values. At least one of mappedBy | filteredBy must be defined, otherwise, an error will be issued.


Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public class Category extends JelloEntity {
   @KeyElement
   public Integer id;

   @Expose @NotPersistent @Association(mappedBy="category")  
   public List<Product> products;	
	
   @Expose @NotPersistent @Association(mappedBy="category", filteredBy="price<99")  
   public List<Product> cheapestInCategory;	   
}

public class Product extends JelloEntity {
   ....
   @Expose
   public Integer price;
	
   @Expose @Reference(Category.class)
   public Key category;	
}

JAVA API

jello.model.JelloEntity.getAssociations

public List<? extends JelloEntity> getAssociations(String fieldName) throws IllegalRequestResource

Performs select query and returns association list.


REST API

Read the Deferred Content section to learn how Jello handles associations representation via REST API.

Association Field metadata representation:

/jello/meta/demo/Category

{
   name: "demo.Category",
   ...
   fields: [
      {
         name: "products",
         readOnly: true,
         type: "jello.Association(demo.Product)"
      },
      ...
   }
   ...
}

Count (Not implemented yet)

Preview (Not implemented yet)

Jello support two types of Owned relationships, Embeded and Managed.

Any @PersistenceCapable data class can be used as an embedded or managed object in another data class. For security and performance reasons, the owned class type cannot be a Jello entity or contain Jello entities.

Fields of Embedded type will not be deferred but are always serialized fully. Similarly, you set a value to embedded type via REST (Create, Update, Patch) call by passing the complete serialized field value.

Deferred Content

Embedded type

Embedded entities allow you to model a field value using a class without creating a new database entity and forming a relationship. The fields of the object value are stored directly in the database entity of the containing object.

If you give the class to embed the @EmbeddedOnly annotation, the class can only be used as an embedded class.

Collections of embeded types are not supported. Use Managed relationship instead.

Here is an example of an embedded class. This example makes the embedded 'Address' class an inner class of the data class that uses it. This is useful, but not required to make a class embeddable.

public class Supplier extends JelloEntity {
   @KeyElement @Expose 
   Integer id;
	
   @Embedded @Expose
   Address address;

   ... 
	
   @PersistenceCapable
   public static class Address {
      String street;
      String city;
      String state;
      String zipCode;
      String country;
   }
}

Use the dot notation to query on embeded fileds:

http://localhost:8888/jello/data/demo/Supplier?$filter=address.street eq "1950 El Camino Real"

Managed type

You model a Managed relationships the same way like you model embedded types but without the @Embedded annotation. Under the hood, the managed field's objects are stored in a separate table in the database but Jello will keep track after the changes made to the own entity and, if necessary, will delete/replace the managed objects.

Managed type fields are not been indexed and therefore cannot be used in a filter query.

@Expose 
public Address managedAddress;

@Expose 
public List<Address> addressesList;

@Expose 
public Set<Address> addressesSet;

@PersistenceCapable
static class Address {
   String street;
   String city;
   String state;
   String zipCode;
   String country;	
}

To conserve resources (bandwidth, CPU, DB calls, and so on), Jello will defer sending Reference and Associations entries unless the client explicitly asked for them using the $expand option. This provides a way for a client to state which associated entities should be represented inline.

As shown in the example below, by default properties that represent links (the "cast" and "director" properties in the example) are represented as an object with a "__deferred" name/value pair to indicate the service deferred representing the related Entries. The uri name/value pair within the "__deferred" object can be used to retrieve the deferred content.

Deferred Content

Note: As shown in the example above, the deferred uri entry contains the entity's key. The entity key is composed of all fields annotated with @KeyElement. The entity's key will be visible via REST API (as part of Deferred links uri) regardless of the element's accessibility definition.

In many cases, it is desired to display a sneak peek (preview) information for deferred references and associations. With Jello, you can specify a field element to be used as the preview content appended inline the deferred entry.

@Preview (jello.ux.Preview)

Syntax:

@Preview(element = "<preview-field-name>")

Here is an example of a preview field. This example makes use of a calculated field. Using a calculated field to render preview content can be useful, but not required for preview field.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@PersistenceCapable @Accessible
public class Casting extends JelloEntity {
   @KeyElement @Expose
   @Reference(Actor.class)
   @Preview(element = "preview")
   Key star;

   ...
}

@PersistenceCapable @Accessible
public class Actor extends JelloEntity {
   @Expose @NotPersistent
   private String preview;
   public String preview() throws IllegalRequestResource {
      String imgUrl = "/assets/img/no_photo.jpg";
      try {
         imgUrl = AttachmentService.getUnsecuredDirectImageUrl(photo);
      } catch(IllegalRequestResource e){}
		
      return "<img src='" + imgUrl + "' style='height:40px;'>  " +  name;
   }
   ...
}

Preview

Preview

Preview metadata

As with any other jello.ux annotation, the preview metadata will be returned as part of the entity metadata. This information can be used by a client to display the appropriate references preview value.

Preview

Inline count

You can use the $inlinecount REST query option to include Associations count as shown below.

Deferred Content

Expand

As described in the $$expand Query Option section, a query request may include the $expand option to explicitly request that a linked to Entity or Associated collection of Entities be serialized inline, rather than deferred. For example, a single 'Movie' Instance with its related 'director' and 'cast' serialized inline as shown in the example below.

Deferred Content

Last updated April 29, 2016.