Defining an entity schema

An ObjectGrid can have any number of logical entity schemas. Entities are defined using annotated Java™ classes, XML, or a combination of both XML and Java classes. Defined entities are then registered with an eXtreme Scale server and bound to backing maps, indexes and other plug-ins.

When designing an entity schema, you must complete the following tasks:
  1. Define the entities and their relationships.
  2. Configure the eXtreme Scale.
  3. Register the entities with the eXtreme Scale.
  4. Create applications that interact with the eXtreme Scale, entity manager, and entities.

Entity schema configuration

An entity schema is a set of entities and the relationships between the entities. In an eXtreme Scale with multiple partitions, the following restrictions and options apply to entity schemas: Entities are registered with an eXtreme Scale before it is initialized. Each defined entity must be uniquely named and is automatically bound to an eXtreme Scale backing map of the same name. The initialization method varies depending on the configuration you are using:

Stand-alone eXtreme Scale

If you are using a stand-alone eXtreme Scale configuration, you can programmatically configure the entity schema. In this mode, you can use the ObjectGrid.registerEntities methods to register annotated entity classes or an entity metadata descriptor file.

Distributed eXtreme Scale configuration

If you are using a distributed eXtreme Scale configuration, you must provide an entity metadata descriptor file with the entity schema.

Entity class requirements

Entities are identified by associating various metadata with a Java class. The metadata can be specified usingJava Platform, Standard Edition 5 annotations, an entity metadata descriptor file, or a combination of annotations and the descriptor file. Entity classes must meet the following criteria: Entities all have a unique name and type. The name, if using annotations, is the simple (short) name of the class by default, but can be overridden using the name attribute of the @Entity annotation.

Persistent attributes

The persistent state of an entity is accessed by clients and the entity manager by using either fields (instance variables) or Enterprise JavaBeans-style property accessors. Each entity must define either field or property-based access. Annotated entities are field-access if the class fields are annotated and are property-access if the getter method of the property is annotated. A mixture of field and property-access is not allowed. If the type cannot be automatically determined, the accessType attribute on the @Entity annotation or equivalent XML can be used to identify the access type.

Persistent fields
Field-access entity instance variables are accessed directly from the entity manager and clients. Fields that are marked with the transient modifier or transient annotation are ignored. Persistent fields must not have final or static modifiers.
Persistent properties
Property-access entities must adhere to the JavaBeans™ signature conventions for read and write properties. Methods that do not follow JavaBeans conventions or have the Transient annotation on the getter method are ignored. For a property of type T, there must be a getter method: T getProperty() and a setter method: void setProperty(T). For boolean types, the getter method can be expressed as boolean isProperty(). Persistent properties must not have the static modifier.
Supported attribute types
The following persistent field and property types are supported:
  • Java primitive types including wrappers
  • java.lang.String
  • java.math.BigInteger
  • java.math.BigDecimal
  • java.util.Date
  • java.util.Calendar
  • java.sql.Date
  • java.sql.Time
  • java.sql.Timestamp
  • byte[]
  • java.lang.Byte[]
  • char[]
  • java.lang.Character[]
  • enum
User serializable attribute types are supported but have performance, query and change-detection limitations. Persistent data that cannot be proxied, such as arrays and user serializable objects, must be reassigned to the entity if altered.

Entity associations

Bi-directional and uni-directional entity associations, or relationships between entities can be defined as one-to-one, many-to-one, one-to-many and many-to-many. The entity manager automatically resolves the entity relationships to the appropriate key references when storing the entities in the eXtreme Scale.

The eXtreme Scale is a data cache and does not enforce referential integrity like a database. Although relationships allow cascading persist and remove operations for child entities, it does not detect or enforce broken links to objects. When removing a child object, the reference to that object must be removed from the parent.

IF you define a bi-directional association between two entities, you must identify the owner of the relationship. In a many association, the many-side of the relationship is always the owning side. If ownership cannot be determined automatically, then the mappedBy attribute of the annotation, or XML equivalent, must be specified. The mappedBy attribute identifies the field in the target entity that is the owner of the relationship. This attribute also helps identify the related fields when there are multiple attributes of the same type and cardinality.

Single valued associations

One-to-one and many-to-one associations are denoted using the @OneToOne and @ManyToOne annotations or equivalent XML attributes. The target entity type is determined by the attribute type. In the following example, we have a uni-directional association between Person and Address. The Customer entity has a reference to one Address entity. In this case, the association could also be many-to-one since there is no inverse relationship.
@Entity
public class Customer {
  @Id id;
  @OneToOne Address homeAddress;
}

@Entity
public class Address{
  @Id id
  @Basic String city;
}
To specify a bi-directional relationship between the Customer and Address classes, add a reference to the Customer class from the Address class and add the appropriate annotation to mark the inverse side off the relationship. Because this association is one-to-one, you must specify an owner of the relationship using the mappedBy attribute on the @OneToOne annotation.
@Entity
public class Address{
  @Id id
  @Basic String city;
  @OneToOne(mappedBy="homeAddress") Customer customer;
}

Collection valued associations

One-to-many and many-to-many associations are denoted using the @OneToMany and @ManyToMany annotations or equivalent XML attributes. All many relationships are represented using types: java.util.Collection, java.util.List or java.util.Set. The target entity type is determined by the generic type of the Collection, List or Set or explicitly using the targetEntity attribute on the @OneToMany or @ManyToMany annotation (or XML equivalent).
In the previous example, it is not practical to have one address object per customer because many customers might share an address or might have multiple addresses. This situation is better solved using a many association:
@Entity
public class Customer {
  @Id id;
  @ManyToOne Address homeAddress;
  @ManyToOne Address workAddress;
}

@Entity
public class Address{
  @Id id
  @Basic String city;
  @OneToMany(mappedBy="homeAddress") Collection<Customer> homeCustomers;


  @OneToMany(mappedBy="workAddress", targetEntity=Customer.class) 
		Collection workCustomers;
}
In this example, two different relationships exist between the same entities: a Home and Work address relationship. A non-generic Collection is used for the workCustomers attribute to demonstrate how a to use the targetEntity attribute when generics are not available.

Primary keys

All entities must have a primary key and can be a simple (single attribute) or composite (multiple attribute) key. The key attributes are denoted using the Id annotation or defined in the entity XML descriptor file. Key attributes have the following requirements: Composite primary keys can optionally define a primary key class. An entity is associated with a primary key class using the @IdClass annotation or the defined in the entity xml descriptor file. An @IdClass annotation is useful when used in conjunction with the EntityManager.find method.
Primary key classes have the following requirements:
  • The primary key class must have be public and have a public no-arg constructor.
  • The access type of the primary key class is determined by the entity that declares the primary key class.
  • If property-access, the properties of the primary key class must be public or protected.
  • The primary key fields or properties must match the key attribute names and types defined in the referencing entity.
  • Primary key classes must implement the equals and hashCode methods.
@Entity
@IdClass(CustomerKey.class)
public class Customer {
    @Id @ManyToOne Zone zone;
    @Id int custId;
    String name;
    ...
}

@Entity
public class Zone{
    @Id String zoneCode;
    String name;
}

public class CustomerKey {
    Zone zone;
    int custId;

    public int hashCode() {...}
    public boolean equals(Object o) {...}
}

Entity proxies and field interception

Entity classes and mutable supported attribute types are extended by proxy classes for property-access entities and bytecode-enhanced for Java Development Kit (JDK) 5 field-access entities. All access to the entity, even by internal business methods and the equals methods, must use the appropriate field or property access methods.

Proxies and field interceptors are used to allow the entity manager to track the state of the entity, determine if the entity has changed, and improve performance. Field interceptors are only available on Java SE 5 platforms when the entity instrumentation agent is configured.

Attention: When using property-access entities, the equals method should use the instanceof operator for comparing the current instance to the input object. All introspection of the target object should be through the object's properties and not the fields themselves as the object instance will be the proxy.