Apache Cayenne > Index > Cayenne Examples > Mapping JTS Geometries
The JTS Topology Suite is a very nice library for handling geometries in Java. On a related subject, for doing spatial operations in the database, use something like PostGIS http://www.postgis.org/.
This is an ExtendedType that stores/reads a JTS Geometry as a WKT (Well-Known Text as defined by OpenGis Consortium).
WKTGeometryType.java
package cayenne.examples; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Types; import org.apache.cayenne.access.types.AbstractType; import org.apache.cayenne.map.DbAttribute; import org.apache.cayenne.validation.BeanValidationFailure; import org.apache.cayenne.validation.ValidationResult; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.io.WKTReader; /** * An ExtendedType that can be used by cayenne to covert WKT to/from JTS * Geometry - com.vividsolutions.jts.geom.Geometry * * http://www.jump-project.org/project.php?PID=JTS&SID=OVER * http://www.objectstyle.org/cayenne/userguide/access-stack/extended-types.html */ public class WKTGeometryType extends AbstractType { private static final String CHARSET = "UTF-8"; private Class geometryClass; public WKTGeometryType(Class geometryClass) { this.geometryClass = geometryClass; } public String getClassName() { return geometryClass.getName(); } public boolean validateProperty(Object source, String property, Object value, DbAttribute dbAttribute, ValidationResult validationResult) { Geometry g = (Geometry) value; if (!g.isValid()) { String msg = "Invalid geometry"; validationResult.addFailure(new BeanValidationFailure(source, property, msg)); return false; } return true; } public void setJdbcObject(PreparedStatement statement, Object value, int pos, int type, int precision) throws Exception { Geometry g = (Geometry) value; switch (type) { case Types.BLOB: statement.setBytes(pos, g.toText().getBytes(CHARSET)); break; default: statement.setString(pos, g.toText()); break; } } public Object materializeObject(ResultSet rs, int index, int type) throws Exception { String wkt = null; switch (type) { case Types.BLOB: wkt = new String(rs.getBytes(index), CHARSET); break; default: wkt = rs.getString(index); break; } if (wkt == null) { return (Geometry) null; } // create WKTReader using application ThreadLocal GeometryFactory return new WKTReader(GeometryHelper.geometryFactory()).read(wkt); } public Object materializeObject(CallableStatement rs, int index, int type) throws Exception { String wkt = null; switch (type) { case Types.BLOB: wkt = new String(rs.getBytes(index), CHARSET); break; default: wkt = rs.getString(index); break; } if (wkt == null) { return (Geometry) null; } // create WKTReader using application ThreadLocal GeometryFactory return new WKTReader(GeometryHelper.geometryFactory()).read(wkt); } }
Register this extended type.
ExtendedTypeMap extendedTypes = node.getAdapter().getExtendedTypes();
extendedTypes.registerType(new WKTGeometryType(Geometry.class));