www.espertech.comDocumentation
This section provides information for using Plain-Old or Bean Java Objects to represent events.
For NEsper .NET also see Section H.7, “.NET Object Events”.
Plain-old Java object events are object instances that expose event properties through JavaBeans-style getter methods. Events classes or interfaces do not have to be fully compliant to the JavaBean specification; however for the Esper engine to obtain event properties, the required JavaBean getter methods must be present or an accessor-style and accessor-methods may be defined via configuration.
Esper supports JavaBeans-style event classes that extend a superclass or implement one or more interfaces. Also, Esper event pattern and EPL statements can refer to Java interface classes and abstract classes.
Classes that represent events should be made immutable. As events are recordings of a state change or action that occurred in the past, the relevant event properties should not be changeable. However this is not a hard requirement and the Esper engine accepts events that are mutable as well.
The hashCode
and equals
methods do not need to be implemented. The implementation of these methods by a Java event class does not affect the behavior of the engine in any way.
Please see Chapter 16, Configuration on options for naming event types represented by Java object event classes. Java classes that do not follow JavaBean conventions, such as legacy Java classes that expose public fields, or methods not following naming conventions, require additional configuration. Via configuration it is also possible to control case sensitivity in property name resolution. The relevant section in the chapter on configuration is Section 16.4.1.3, “Non-JavaBean and Legacy Java Event Classes”.
As outlined earlier, the different property types are supported by the standard JavaBeans specification, and some of which are uniquely supported by Esper:
Simple properties have a single value that may be retrieved. The underlying property type might be a Java language primitive (such as int, a simple object (such as a java.lang.String), or a more complex object whose class is defined either by the Java language, by the application, or by a class library included with the application.
Indexed - An indexed property stores an ordered collection of objects (all of the same type) that can be individually accessed by an integer-valued, non-negative index (or subscript).
Mapped - As an extension to standard JavaBeans APIs, Esper considers any property that accepts a String-valued key a mapped property.
Nested - A nested property is a property that lives within another Java object which itself is a property of an event.
Assume there is an NewEmployeeEvent
event class as shown below. The mapped and indexed properties in this example return Java objects but could also return Java language primitive types (such as int or String). The Address
object and Employee
can themselves have properties that are nested within them, such as a street name in the Address
object or a name of the employee in the Employee
object.
public class NewEmployeeEvent { public String getFirstName(); public Address getAddress(String type); public Employee getSubordinate(int index); public Employee[] getAllSubordinates(); }
Simple event properties require a getter-method that returns the property value. In this example, the getFirstName
getter method returns the firstName
event property of type String.
Indexed event properties require either one of the following getter-methods. A method that takes an integer-type key value and returns the property value, such as the getSubordinate
method, or a method that returns an array-type, or a class that implements Iterable
. An example is the getAllSubordinates
getter method, which returns an array of Employee but could also return an Iterable
. In an EPL or event pattern statement, indexed properties are accessed via the property[index]
syntax.
Mapped event properties require a getter-method that takes a String-typed key value and returns the property value, such as the getAddress
method. In an EPL or event pattern statement, mapped properties are accessed via the property('key')
syntax.
Nested event properties require a getter-method that returns the nesting object. The getAddress
and getSubordinate
methods are mapped and indexed properties that return a nesting object. In an EPL or event pattern statement, nested properties are accessed via the property.nestedProperty
syntax.
All event pattern and EPL statements allow the use of indexed, mapped and nested properties (or a combination of these) anywhere where one or more event property names are expected. The below example shows different combinations of indexed, mapped and nested properties in filters of event pattern expressions (each line is a separate EPL statement):
every NewEmployeeEvent(firstName='myName') every NewEmployeeEvent(address('home').streetName='Park Avenue') every NewEmployeeEvent(subordinate[0].name='anotherName') every NewEmployeeEvent(allSubordinates[1].name='thatName') every NewEmployeeEvent(subordinate[0].address('home').streetName='Water Street')
Similarly, the syntax can be used in EPL statements in all places where an event property name is expected, such as in select lists, where-clauses or join criteria.
select firstName, address('work'), subordinate[0].name, subordinate[1].name from NewEmployeeEvent(address('work').streetName = 'Park Ave')
Property names follows Java standards: the class java.beans.Introspector
and method getBeanInfo
returns the property names as derived from the name of getter methods. In addition, Esper configuration provides a flag to turn off case-sensitive property names. A sample list of getter methods and property names is:
Table C.1. JavaBeans-style Getter Methods and Property Names
Method | Property Name | Example |
---|---|---|
getPrice() | price | select price from MyEvent |
getNAME() | NAME | select NAME from MyEvent |
getItemDesc() | itemDesc | select itemDesc from MyEvent |
getQ() | q | select q from MyEvent |
getQN() | QN | select QN from MyEvent |
getqn() | qn | select qn from MyEvent |
gets() | s | select s from MyEvent |
When your getter methods or accessor fields return a parameterized type, for example Iterable<MyEventData>
for an indexed property or Map<String, MyEventData>
for a mapped property, then property expressions may refer to the properties available through the class that is the type parameter.
An example event that has properties that are parameterized types is:
public class NewEmployeeEvent { public String getName(); public Iterable<EducationHistory> getEducation(); public Map<String, Address> getAddresses(); }
A sample of valid property expressions for this event is shown next:
select name, education, education[0].date, addresses('home').street from NewEmployeeEvent
An EPL statement may update indexed or mapped properties of an event, provided the event class exposes the required setter method.
The setter method for indexed properties must be named set
PropertyName and must take two parameters: the int
-type index and the Object
type new value.
The setter method for mapped properties must be named set
PropertyName and must take two parameters: the String
-type map key and the Object
type new map value.
The following is an example event that features a setter method for the props
mapped property and for the array
indexed property:
public class MyEvent { private Map props = new HashMap(); private Object[] array = new Object[10]; public void setProps(String name, Object value) { props.put(name, value); } public void setArray(int index, Object value) { array[index] = value; } // ... also provide regular JavaBean getters and setters for all properties
This sample statement updates mapped and indexed property values:
update istream MyEventStream set props('key') = 'abc', array[2] = 100
Esper employs byte code generation for fast access to event properties. When byte code generation is unsuccessful, the engine logs a warning and uses Java reflection to obtain property values instead.
A known limitation is that when an interface has an attribute of a particular type and the actual event bean class returns a subclass of that attribute, the engine logs a warning and uses reflection for that property.