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
2 comments:
Hi Doug, is the above still valid?
I get a couple of exceptions:
Exception [TOPLINK-6015] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.QueryException
Exception Description: Object comparisons can only use the equal() or notEqual() operators. Other comparisons must be done through query keys or direct attribute level comparisons.
Expression: [
Relation operator >
Query Key id
Base testoraclegeometry.FeatureOfInterest
Constant 0]
If I modify SS_SessionCustomizer to remove the ">" from:
Expression idExp = eb.get("id").greaterThan(0); raq.setSelectionCriteria(idExp.and(relateExp));
to: raq.setSelectionCriteria(relateExp);
I get:
Exception [TOPLINK-6015] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.QueryException
Exception Description: Invalid query key [geometry] in expression.
OK, I figured it out - "geometry" is a column name in your SimpleSpatial table ;-)
Post a Comment