Skip to content

Spatial starter#255

Merged
markxnelson merged 17 commits intomainfrom
spatial-starter
Apr 1, 2026
Merged

Spatial starter#255
markxnelson merged 17 commits intomainfrom
spatial-starter

Conversation

@markxnelson
Copy link
Copy Markdown
Member

📌 Description

Adds a new Oracle Spatial starter for the database starters project, including:

  • oracle-spring-boot-spatial-data-tools with Spring Boot auto-configuration and GeoJSON-first Oracle Spatial helpers
  • oracle-spring-boot-starter-spatial as the thin dependency starter
  • oracle-spring-boot-sample-spatial as a REST sample backed by Oracle Spatial and Testcontainers

The new starter provides:

  • OracleSpatialGeoJsonConverter for SDO_UTIL.FROM_GEOJSON and SDO_UTIL.TO_GEOJSON
  • OracleSpatialSqlBuilder for SDO_FILTER, SDO_RELATE, SDO_WITHIN_DISTANCE, and SDO_NN
  • OracleSpatialProperties with oracle.database.spatial.* configuration

This PR also includes:

  • Oracle Free Testcontainers integration tests for the spatial data-tools module
  • end-to-end sample test coverage for the spatial sample
  • review-driven follow-up fixes for query correctness, auto-configuration coverage, configuration metadata/Javadoc, seed SQL consistency, and README/docs improvements

✅ Checklist

  • Code builds and runs locally
  • Tests have been added/updated (if applicable)
  • Documentation has been updated (if applicable)
  • Follows project coding style and conventions
  • Signed the Oracle Contributor Agreement (OCA) to contribute to this project

🔗 Related Issue

n/a

📸 Screenshots / Logs (if applicable)

Test commands run successfully:

mvn -pl oracle-spring-boot-spatial-data-tools clean test
mvn -pl oracle-spring-boot-starter-samples/oracle-spring-boot-sample-spatial -am clean test

Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Apr 1, 2026
@markxnelson markxnelson self-assigned this Apr 1, 2026
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
andytael
andytael previously approved these changes Apr 1, 2026
Copy link
Copy Markdown
Member

@andytael andytael left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

assertThat(properties.getDefaultDistanceUnit()).isEqualTo("M");
assertThat(converter.fromGeoJsonSql(":geometry")).isEqualTo("SDO_UTIL.FROM_GEOJSON(:geometry, null, 4326)");
assertThat(converter.distanceClause(500)).isEqualTo("distance=500 unit=M");
assertThat(sqlBuilder.withinDistancePredicate("geometry", "shape", 500))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably should not use string sql builders. can something similar be done with jdbcclient?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are just helpers to create geospatial sql fragments, that are then actually used in a JdbcClient when we want to run a query (see LandmarkService for example)

Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
@anders-swanson
Copy link
Copy Markdown
Member

general q's:

  1. are there any spring APIs we can wire into for this starter? If we can do something with RowMapper, JdbcClient, Converter, for SDO_GEOMETRY?
  2. for raw strings helper utility, I think it should probably be avoided. String SQL fragments disconnected from Spring or JDBC seem problematic.
  3. can we do anything for spatial repositories?

Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
anders-swanson
anders-swanson previously approved these changes Apr 1, 2026
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
}

@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
Copy link
Copy Markdown
Member

@anders-swanson anders-swanson Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we're doing rs.getString(), when would I use this over a plain row mapper?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gpt says:

The main value is not that it does something rs.getString() cannot do. The value is that it gives the starter a small, explicit Spring JDBC integration point for the common case of projecting SDO_UTIL.TO_GEOJSON(...) back to a GeoJSON String.

So the reasons to use it over an inline lambda are:

  • it makes the intent obvious: spatial.geoJsonRowMapper("geometry") reads as “map this projected spatial column as GeoJSON”
  • it avoids repeating the same one-line mapper everywhere
  • it gives the starter at least one concrete RowMapper integration hook, which was part of the review feedback
  • it gives us a stable place to evolve behavior later if Oracle/JDBC handling ever needs to be less trivial than getString()

That said, I think the reviewer’s instinct is fair: today it is a very thin wrapper. So I’d probably add that if the team feels this is too small to justify a public class, I’d be comfortable with either:

  • keeping geoJsonRowMapper(...) on OracleSpatialJdbcOperations but making the implementation class non-public, or
  • inlining it and dropping the named class entirely

My own preference would be:

  • keep the geoJsonRowMapper(...) factory method as the public API
  • make OracleSpatialGeoJsonRowMapper an internal implementation detail if we want to reduce surface area

So the short answer is: it is about starter-level Spring integration and readability, not extra mapping power today.

wdyt @anders-swanson

Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
}

@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
Copy link
Copy Markdown
Member

@anders-swanson anders-swanson Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also curious if geojson we can return as OSON? Java string doesn't seem too useful - thoughts? maybe we can offer rowmapper to cast geojson as a java object? would have to learn a bit more about how spatial best works with JDBC to offer a good suggestion here

@Test
void geoJsonRoundTrip() {
SpatialExpression geometry = spatial.toGeoJson("geometry");
String geoJson = jdbcClient.sql("select " + geometry.selection("geometry") + " from landmarks where id = :id")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the plan said not to use string SQL fragments but this still looks like SQL concatenation

Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
Signed-off-by: Mark Nelson <mark.x.nelson@oracle.com>
@@ -0,0 +1,48 @@
create table if not exists landmarks (
id number primary key,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe use generated ID? (id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY)


public Landmark getById(Long id) {
SpatialExpression geometry = spatial.toGeoJson("geometry");
return jdbcClient.sql("select id, name, category, "
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@markxnelson markxnelson merged commit ac7f348 into main Apr 1, 2026
4 checks passed
@markxnelson markxnelson deleted the spatial-starter branch April 1, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants