We just made our first milestone build available for download. See the EclipseLink team blog for more information.
This is an important step for our project. Our plan is to produce monthly milestone builds as we work toward our 1.0 release. It does seem very odd to be starting back at a 1.0 release after over 10 years of shipping this Java persistence solution. For those familiar with TopLink this milestone is the complete capabilities from the Oracle TopLink 11gR1 Technology Preview 2. Since we were near completion of our development cycle for this release the new features available are complete and well tested.
We are also in the process of publishing the complete documentation from Oracle TopLink as the EclipseLink user manuals. This will be done on the wiki. This in conjunction with the evolving set of examples should help developers easily evaluate the use of this project.
Any and all feedback is appreciated. There is a newsgroup and users mailing list where feedback can be provided.
All information on the EclipseLink project can be found linked from our home page.
Cheers,
Doug
A blog dedicated to Java Persistence issues and solutions related to EclipseLink and Oracle TopLink.
Wednesday, November 7, 2007
Friday, August 24, 2007
Friday, July 6, 2007
Its alive...
I am just heading out on vacation this morning and wanted to update the community on our progress in the Eclipse new project process. We have completed our initial incubation provisioning of the Eclipse Persistence Services Project (EclipseLink).
We now have our home page up (www.eclipse.org/eclipselink) with a wiki home and developer mailing list.
We are initiating the Eclipse Parallel IP review process to get the TopLink source and test case contribution into the subversion repository in the near future. This process of re-packaging and organizing the source has been very interesting.
In the coming weeks we'll get the source code in and builds and testing working. We'll publish our roadmap and focus on building new features and a strong community. Stay tuned....
Doug
We now have our home page up (www.eclipse.org/eclipselink) with a wiki home and developer mailing list.
We are initiating the Eclipse Parallel IP review process to get the TopLink source and test case contribution into the subversion repository in the near future. This process of re-packaging and organizing the source has been very interesting.
In the coming weeks we'll get the source code in and builds and testing working. We'll publish our roadmap and focus on building new features and a strong community. Stay tuned....
Doug
Friday, June 8, 2007
Eclipse Persistence Services Project - Passed Creation Review
We are now busy working through the logistics of provisioning the product and getting the initial code contribution available through the parallel IP process.
If you have any questions please post them to the forum.
Cheers,
Doug
If you have any questions please post them to the forum.
Cheers,
Doug
Wednesday, April 25, 2007
Simple Auditing using TopLink JPA
In a forum post on the Oracle TopLink forum on OTN there was a request for an approach to tracking entity history in a separate table. While Oracle TopLink includes support for automatic historical versioning this support does not exist in TopLink Essentials.
The following is a simple example for how you might do historical versioning of your persistent entities using TopLink Essentials and JPA. There are many approaches to how you would design your schema for managing this additional state. I kept my approach simple where the primary data table uses an integer version optimistic locking column and the history table stores a row for each version of the primary table.
The sample model is simply an Employee entity and its history is stored in an EmployeeHistory entity.
Now to have the creation and modification of all Employee instances cause the creation of an EmployeeHistory instance I will use a TopLink Essentials specific event listener.
The descriptor event listener used looks like:
I hope you find this helpful.
Doug
The following is a simple example for how you might do historical versioning of your persistent entities using TopLink Essentials and JPA. There are many approaches to how you would design your schema for managing this additional state. I kept my approach simple where the primary data table uses an integer version optimistic locking column and the history table stores a row for each version of the primary table.
The sample model is simply an Employee entity and its history is stored in an EmployeeHistory entity.
@Entity
@NamedQuery(name = "Employee.findAll",
query = "select e from Employee e ORDER BY e.lastName ASC, e.firstName ASC")
@TableGenerator(name = "emp-seq-table", table = "SEQUENCE",
pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT",
pkColumnValue = "EMP_SEQ", allocationSize = 26)
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.TABLE,
generator = "emp-seq-table")
@Column(name = "EMP_ID", nullable = false)
private int id;
@Column(name = "F_NAME")
private String firstName;
@Column(name = "L_NAME")
private String lastName;
private String gender;
@Version
private long version;
...
@Entity
@IdClass(EmployeeHistory.ID.class)
@Table(name = "EMPLOYEE_HISTORY")
@NamedQuery(name="EmployeeHistory.findAllForEmployee", query="SELECT eh FROM EmployeeHistory eh WHERE eh.employee = :EMP")
public class EmployeeHistory {
@Id
@Column(name = "EMP_ID")
private int id;
@Id
private long version;
@ManyToOne
@JoinColumn(name = "EMP_ID", referencedColumnName = "EMP_ID", insertable=false, updatable=false)
private Employee employee;
@Column(name = "F_NAME")
private String firstName;
@Column(name = "L_NAME")
private String lastName;
private String gender;
/**
*
* @param emp
*/
protected EmployeeHistory(Employee emp) {
this.id = emp.getId();
this.version = emp.getVersion();
this.firstName = emp.getFirstName();
this.lastName = emp.getLastName();
this.gender = emp.getGender();
this.employee = emp;
}
...
Now to have the creation and modification of all Employee instances cause the creation of an EmployeeHistory instance I will use a TopLink Essentials specific event listener.
The descriptor event listener used looks like:
/**Now with this event listener in place I can proceed in my application using standard JPA coding. Every time I create or modify an Employee entity I will see the associated EmployeeHistory INSERT during the transaction commit.
* This is an example of how a TopLink Essentials DescriptorEventListener can be
* used to populate an audit record whenever an update occurs. This class must be
* registered as a persistence unit property in the creation of the
* EntityManagerFactory.
*
* property name="toplink.descriptor.customizer.Employee" value="model.jpa.auditing.EmployeeAuditingHandler"
*
* @since TopLink Essentials v2-Build-41
*/
public class EmployeeAuditingHandler extends DescriptorEventAdapter implements DescriptorCustomizer {
/**
* This is where the real work of this class happens. For any INSERT or UPDATE
* operation an INSERT of a new history object is forced.
*/
private void insertEmployeeHistory(DescriptorEvent event) {
EmployeeHistory empHist = new EmployeeHistory((Employee)event.getSource());
InsertObjectQuery insertQuery = new InsertObjectQuery(empHist);
event.getSession().executeQuery(insertQuery);
}
public void aboutToUpdate(DescriptorEvent event) {
insertEmployeeHistory(event);
}
public void aboutToInsert(DescriptorEvent event) {
insertEmployeeHistory(event);
}
/**
* This method is invoked through this class's registration as a descriptor
* customizer. All it does is register this same object as an event listener
*/
public void customize(ClassDescriptor descriptor) {
descriptor.getEventManager().addListener(this);
}
}
I hope you find this helpful.
Doug
Sunday, April 22, 2007
TopLink Essentials using Oracle Spatial ... a sample application
Andrejus Baranovskis has posted a sample application using Oracle Spatial with TopLink Essentials JPA. The steps are based upon my previous post.
andrejusb.blogspot.com
Doug
andrejusb.blogspot.com
Doug
Thursday, April 12, 2007
Oracle Spatial using TopLink Essentials JPA
As discussed in my previous post the usage of Oracle Database Spatial support is definitely growing in popularity. This post describes how TopLink Essentials, the reference implementation of JPA within GlassFish, can be extended to support mapping to MDSYS.SDO_GEOMETRY columns and leveraging the Oracle Spatial custom SQL operators within your queries.
Extending TopLink Essentials (TLE) for Spatial support involves a couple of key steps:
- A custom database platform is required to handle the STRUCT <-> JGeometry (oracle.spatial.geometry) conversions and statement binding.
- Customize the mappings to ensure the default serialized mapping for the unknown JGeometry type is not used.
- Usage of custom TLE expression operators for defining the queries.
1. Custom Database Platform
TLE uses a target database configuration to control custom SQL generation leveraging the different dialects supported by each of the database vendors. The platform is automatically detected by default but can be specified. For our purposes we will write a custom database platform extending the shipped OraclePlatform. To configure the use of our custom platform a persistence unit property (toplink.target-database) will need to be set.
The custom platform must be written and packaged where the class-loader can access it.
Here is an example of what that platform might look like. Oracle10SpatialPlatform.java
<property name="toplink.target-database" value ="oracle.toplink.essentials.extension.spatial.Oracle10SpatialPlatform"/> |
The custom platform must be written and packaged where the class-loader can access it.
Here is an example of what that platform might look like. Oracle10SpatialPlatform.java
2. Customizing the Mappings
The default mapping with JPA is to consider unknown types to be serialized basic (direct to field) mappings. In the case of JGeometry attribute types it is up to the developer to remove the converter that will be configured by default. The following descriptor customizer illustrates how the converter can be easily removed.
|
3. Using Custom Expression Operators
While the above two steps are pretty straight forward with one time configurations the more involved process is using spatial operators across dynamic and named queries. Based on a set of custom expression operators the following examples illustrate how a named query definition and usage might look.
EXAMPLE: Defining a Named Query with Custom Spatial Operators |
Now to execute the above query within the application code standard JPA usage is followed.
In order to make all of this work a couple of helper classes are required to define the spatial operators and parameters.
SpatialOperator: Captures the definition of expression operators and acts as a factory for function expressions for use in queries.
SpatialParameters: Simplifies configurations of parameters for the MDSYS spatial operators
These classes must be compiled and made available on the application's classpath or packaged within a JAR with TopLink Essentials.
EXAMPLE: Invoking the Named Query |
In order to make all of this work a couple of helper classes are required to define the spatial operators and parameters.
SpatialOperator: Captures the definition of expression operators and acts as a factory for function expressions for use in queries.
SpatialParameters: Simplifies configurations of parameters for the MDSYS spatial operators
These classes must be compiled and made available on the application's classpath or packaged within a JAR with TopLink Essentials.
This support will be available in the next release of Oracle TopLink and will also be included in the initial contribution to EclipseLink. The final API in these version may vary from what I am providing now as a sample of how to extend TopLink.
Doug
Wednesday, April 4, 2007
Using Oracle Spatial with TopLink
I have been working a growing number of customers assisting them with their usage of Oracle Database Spatial support through TopLink. Actually my first exposure with Spatial and TopLink dates back to 1999, long before I joined (through acquisition) Oracle. It was an extended consulting engagement assisting Oracle Consulting in their usage of TopLink on a customer's application. Those Oracle consultants are now my co-workers managing the Oracle Consulting teams I deal with and I am now product manager for TopLink. Our recent work assisting customers in their extensions of TopLink for Spatial data mapping and querying has already produced results (GE Energy Press Release).
TopLink does not offer formal support for Oracle Spatial in the current 10.1.3.X versions or earlier. TopLink can however, be extended to support custom data types and query operators/functions. This post will walk through the basics of extended the expression framework and show some examples using Spatial data types.
In order to have TopLink both read and write SDO_GEOMETRY columns as well as generate the necessary SQL to query these columns two extensions to TopLink need to be made.
TopLink does not offer formal support for Oracle Spatial in the current 10.1.3.X versions or earlier. TopLink can however, be extended to support custom data types and query operators/functions. This post will walk through the basics of extended the expression framework and show some examples using Spatial data types.
In order to have TopLink both read and write SDO_GEOMETRY columns as well as generate the necessary SQL to query these columns two extensions to TopLink need to be made.
- Provide a custom database platform enabling the SDO_GEOMETRY <-> JGeometry (oracle.spatial.geometry) conversion
- Define and use custom expression operators to allow the generation of these operators into SQL
I will leave it to you to read about the Oracle DB's Spatial support in the docs, on OTN or download a sample.
Struct Conversions - Custom Database Platform
The SDO_GEOMETRY object type which is used to store geometries in the database passes through JDBC as a Struct. The spatial Java library provides an implementation of JGeometry (oracle.spatial.geometry) that simplifies conversion and usage within a Java object model. In order to get TopLink to work with JGeometry types in the object model and properly handle the Struct with JDBC a custom database platform is required.
To use these conversions within TopLink you must create a custom DatabasePlatform (most likely a subclass of Oracle10Platform) and incorporate these conversions into the platform.
Note: TopLink's existing support for mapping custom object types (Structs) is not an option with some Oracle Advanced Data Types such as Spatial. An active JDBC connection is required for conversion and the conversions at the mapping level do not necessarily have the connection available.
Example 1: JGeometry - Struct Conversion Code
|
To use these conversions within TopLink you must create a custom DatabasePlatform (most likely a subclass of Oracle10Platform) and incorporate these conversions into the platform.
Custom Expression Operators
TopLink's query framework makes use of expressions for defining the selection criteria as well as for specifying many query configuration options relative to the mapped object model. The expressions are basically a tree node object structure defining navigation through the mapped domain model as well as common query operators. For those of you more familiar with RedHatTM/JBossTM HibernateTM the expression framework provides a super-set of these capabilities to their criteria API.
Using the TopLink expressions developers are able to build very complex queries and have the platform specific SQL generated for them. Expressions also allow the queries to be processed in-memory and avoid unnecessary database trips.
ExpressionOperator
All operations used in expressions are defined by an ExpressionOperator. This capability can be extended to define additional operations.
These operators should be defined only once and re-used as needed when defining specific named or dynamic queries. In the above example a singleton operator (RELATE_OP) is used to store the custom operator.
Preview of Future TopLink Spatial Query API
In the next major release of TopLink we will offer out of the box support for Spatial mapping and querying. The following example illustrates how the same query as above would be written.
This new API incorporates the same expression operator functionality within the SpatialExpressionFactory class. The SpatialParameters provides some easy to use enums for providing the parameter values instead of building the string value yourself. If you do want to provide the string value directly this is also available.
ExpressionOperator
All operations used in expressions are defined by an ExpressionOperator. This capability can be extended to define additional operations. Example 2: SDO_RELATE ExpressionOperator public static ExpressionOperator relateOperator() { ExpressionOperator exOperator = new ExpressionOperator(); exOperator.setType(ExpressionOperator.FunctionOperator); Vector v = NonSynchronizedVector.newInstance(4); v.addElement("MDSYS.SDO_RELATE("); v.addElement(", "); v.addElement(", "); v.addElement(")"); exOperator.printsAs(v); exOperator.bePrefix(); exOperator.setNodeClass(ClassConstants.FunctionExpression_Class); return exOperator; } |
These operators should be defined only once and re-used as needed when defining specific named or dynamic queries. In the above example a singleton operator (RELATE_OP) is used to store the custom operator.
FunctionExpression
To use an ExpressionOperator with specific parameter values a FunctionExpression must be built and incorporated within the selection criteria expression of a TopLink query. Example 3: Using a FunctionExpression in a QueryReadAllQuery raq = new ReadAllQuery(MyEntity.class); |
Preview of Future TopLink Spatial Query API
In the next major release of TopLink we will offer out of the box support for Spatial mapping and querying. The following example illustrates how the same query as above would be written. Example 4: Spatial Queries in the future TopLink release ReadAllQuery raq = new ReadAllQuery(SimpleSpatial.class); ExpressionBuilder eb = raq.getExpressionBuilder(); SpatialParameters params = new SpatialParameters(); params.setMask(Mask.ANYINTERACT); Expression relateExp = SpatialExpressionFactory.relate(eb.get("geometry"), someJGeometry, params); raq.setSelectionCriteria(relateExp); raq.addAscendingOrdering("id"); List<SimpleSpatial> results = (List<SimpleSpatial>)session.executeQuery(raq); |
This new API incorporates the same expression operator functionality within the SpatialExpressionFactory class. The SpatialParameters provides some easy to use enums for providing the parameter values instead of building the string value yourself. If you do want to provide the string value directly this is also available.
Doug
Sunday, April 1, 2007
A new home
With the launching of the Java Persistence Platform Project (aka EclipseLink) I decided to increase the scope of my blog so that it is not focussed just on TopLink. I also wanted to move to a different host.
After working on TopLink in many different roles for over a decade I am looking forward to this new challenge. Delivering a high quality open source solution in an open and transparent manor is our goal. I plan to make this blog my way to express my opinion on persistence related subjects and also deliver technical content to assist in the project's adoption.
Doug
After working on TopLink in many different roles for over a decade I am looking forward to this new challenge. Delivering a high quality open source solution in an open and transparent manor is our goal. I plan to make this blog my way to express my opinion on persistence related subjects and also deliver technical content to assist in the project's adoption.
Doug
Subscribe to:
Posts (Atom)