I finally got some time to play with Cayenne 4.2 and PostGIS [1]. I implemented something similar to Tore's WKTGeometryType, using "org.locationtech.jts:jts-core" lib for geometries. Though it required an extra step: byte[] coming back on select would not convert to Geometry properly. So I had to wrap select column in a PostGIS "ST_AsBinary" function. Luckily Cayenne 4.2 makes it possible, and actually quite easy, as there is a full AST for the generated SQL that can be manipulated [2]. Thanks Nikita, this API is awesome! :)
This is just a POC, and I can think of a few more improvements. E.g.: * Lazy geometry parsing * Support for other geometry representations, such as GeoJSON ("org.wololo:jts2geojson"), that will require other column functions . * Provide a set of custom functions for expressions. * ... I am not yet sure as to the final home of this module. Initially I was planning to use it on a commercial project. But I'd certainly want to distill it to a reusable open source library. Andrus [1] https://github.com/andrus/cayenne-postgis <https://github.com/andrus/cayenne-postgis> [2] https://github.com/andrus/cayenne-postgis/blob/master/src/main/java/org/example/cayenne/postgis/cayenne/PostgisSQLTreeProcessor.java > On Feb 25, 2019, at 10:17 AM, Nikita Timofeev <ntimof...@objectstyle.com> > wrote: > > Hi Andrus, > >> >> 1. Custom functions (already on master - [1]) >> 2. Joins that are not equi-joins (spatial joins [2] in our case - >> ST_Intersects/ST_Contains/etc). >> >> @Nikita - anything else I might have missed? > > Essentially that's it for now. Here are links to related JIRA tasks: > > https://issues.apache.org/jira/browse/CAY-2512 > https://issues.apache.org/jira/browse/CAY-2526 > https://issues.apache.org/jira/browse/CAY-2529 > https://issues.apache.org/jira/browse/CAY-2528 > > On Sat, Feb 23, 2019 at 5:38 PM Andrus Adamchik <and...@objectstyle.org> > wrote: >> >> Hi Tore, >> >> Thanks for sharing your solutions. >> >>> Next up is PostGIS queries. PostGIS queries are very powerful, but the >>> syntax can be quite strange. SQLTemplate or something similar should work >>> fine. I have some simple application specific java abstraction to the most >>> common stuff like ST_Intersects to fetch rows matching a tile and such. >> >> This is primarily the area where we think we might improve Cayenne >> abstractions for both spatial and non-spatial advanced SQL. We'd like to add >> the ability for object queries / mapping to contain the following: >> >> 1. Custom functions (already on master - [1]) >> 2. Joins that are not equi-joins (spatial joins [2] in our case - >> ST_Intersects/ST_Contains/etc). >> >> @Nikita - anything else I might have missed? >> >> None of the above appears to break the basic ORM assumptions, just taking >> them to the next level. So hopefully it won't create leaky abstractions. >> >> Andrus >> >> [1] https://issues.apache.org/jira/browse/CAY-2512 >> [2] http://postgis.net/workshops/postgis-intro/joins.html >> >> >> >> >>> On Feb 23, 2019, at 1:40 AM, Tore Halset <hal...@pvv.ntnu.no> wrote: >>> >>> Hello. >>> >>> With Cayenne, you can easily create a ExtendedType that convert JTS >>> geometries on the java side to Well-Known Binary on the database side. I >>> did create a similar ExtendedType to create JTS geometries to Well-Known >>> Text for storing JTS geometries as text (se below). We have used this in >>> production for several years. For PostGIS, I have not used Cayenne on the >>> geometries, but it should work identical. >>> >>> A long time ago, I wrote about this over at >>> http://objectstyle.org/confluence/display/CAY/Mapping+JTS+Geometries , but >>> that website does not exist anymore. >>> >>> Next up is PostGIS queries. PostGIS queries are very powerful, but the >>> syntax can be quite strange. SQLTemplate or something similar should work >>> fine. I have some simple application specific java abstraction to the most >>> common stuff like ST_Intersects to fetch rows matching a tile and such. >>> >>> For related libraries, JTS has lots of geometry goodies. It is in the >>> middle of a move with package name switch. The old one from vividsolutions >>> is most compatible with other libraries for now. Geotools has lots of >>> goodies for projection and such. And perhaps our library, >>> https://github.com/ElectronicChartCentre/java-vector-tile , for >>> constructing Mapbox Vector Tiles from java for use in Mapbox GL JS or >>> Native. >>> >>> Regards, >>> Tore Halset. >>> >>> /** >>> * An ExtendedType that can be used by cayenne to covert WKT to/from JTS >>> * Geometry - com.vividsolutions.jts.geom.Geometry >>> */ >>> public class WKTGeometryType implements ExtendedType { >>> >>> private static final String CHARSET = "UTF-8"; >>> >>> private Class<? extends Geometry> geometryClass; >>> >>> public WKTGeometryType(Class<? extends Geometry> 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; >>> } >>> return new WKTReader(new 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; >>> } >>> return new WKTReader(new GeometryFactory()).read(wkt); >>> } >>> >>> } >>> >>>> On 21 Jan 2019, at 08:11, Nikita Timofeev <ntimof...@objectstyle.com> >>>> wrote: >>>> >>>> Hi All, >>>> >>>> I had an interesting discussion with my colleagues who use PostGIS and >>>> they are really interested in better support from Cayenne. Well, >>>> actually they can’t use Cayenne on that project, as it will be like >>>> using just raw SQL. >>>> >>>> So I was wondering if anyone else actively uses spacial features and >>>> can help to determine missing parts in Cayenne. Maybe we can push this >>>> forward and get some really nice cayenne-spacial module. >>>> >>>> Any feedback is welcome. >>>> >>>> -- >>>> Best regards, >>>> Nikita Timofeev >>>> >>> >> > > > -- > Best regards, > Nikita Timofeev