Skip to content

Commit

Permalink
fix: JSON column DDL was generated as STRING (#982)
Browse files Browse the repository at this point in the history
* fix: JSON column DDL was generated as STRING

* test: use JSON null values as well
  • Loading branch information
olavloite authored Mar 28, 2024
1 parent da41b42 commit aae5838
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package com.google.cloud.spanner.hibernate;

import static org.hibernate.type.SqlTypes.DECIMAL;
import static org.hibernate.type.SqlTypes.JSON;
import static org.hibernate.type.SqlTypes.NUMERIC;

import com.google.cloud.spanner.hibernate.hints.ReplaceQueryPartsHint;
Expand Down Expand Up @@ -65,6 +66,8 @@
import org.hibernate.type.descriptor.jdbc.BasicBinder;
import org.hibernate.type.descriptor.jdbc.JsonAsStringJdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
import org.jboss.logging.Logger;

/** Hibernate 6.x dialect for Cloud Spanner. */
Expand All @@ -86,7 +89,7 @@ public int executeInsert(

private static class SpannerJsonJdbcType extends JsonAsStringJdbcType {
private SpannerJsonJdbcType() {
super(SqlTypes.LONG32VARCHAR, null);
super(JSON, null);
}

@Override
Expand Down Expand Up @@ -176,6 +179,9 @@ protected String columnType(int sqlTypeCode) {
if (sqlTypeCode == DECIMAL || sqlTypeCode == NUMERIC) {
return "numeric";
}
if (sqlTypeCode == JSON) {
return "json";
}
return super.columnType(sqlTypeCode);
}

Expand All @@ -186,6 +192,14 @@ protected void registerColumnTypes(
JdbcTypeRegistry jdbcTypeRegistry =
typeContributions.getTypeConfiguration().getJdbcTypeRegistry();
jdbcTypeRegistry.addDescriptorIfAbsent(new SpannerJsonJdbcType());
final DdlTypeRegistry ddlTypeRegistry =
typeContributions.getTypeConfiguration().getDdlTypeRegistry();
ddlTypeRegistry.addDescriptor(
new DdlTypeImpl(
SqlTypes.JSON,
columnType(SqlTypes.JSON),
castType(SqlTypes.JSON),
this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@
import com.google.cloud.spanner.hibernate.types.SpannerStringArray;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.util.List;
import org.hibernate.annotations.Type;

@Entity
@Table(indexes = {@Index(name = "idx_singer_active", columnList = "active")})
public class Singer extends AbstractNonInterleavedEntity {

@Column(length = 100)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,15 @@ public List<Venue> generateRandomVenues(int count) {
for (int i = 0; i < count; i++) {
Venue venue = new Venue();
venue.setName(randomDataService.getRandomVenueName());
VenueDescription description = new VenueDescription();
description.setCapacity(random.nextInt(100_000));
description.setType(randomDataService.getRandomVenueType());
description.setLocation(randomDataService.getRandomVenueLocation());
venue.setDescription(description);
if (random.nextBoolean()) {
VenueDescription description = new VenueDescription();
description.setCapacity(random.nextInt(100_000));
description.setType(randomDataService.getRandomVenueType());
description.setLocation(randomDataService.getRandomVenueLocation());
venue.setDescription(description);
} else {
venue.setDescription(null);
}
venues.add(venue);
}
return repository.saveAll(venues);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2019-2024 Google LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/

package com.google.cloud.spanner.sample;

import com.google.cloud.spanner.connection.SpannerPool;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.springframework.boot.SpringApplication;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;

/** Runs the sample application on the emulator. */
@RunWith(JUnit4.class)
public class SampleApplicationEmulatorTest {
private static GenericContainer<?> emulator;

/** Starts the emulator in a test container. */
@BeforeClass
public static void setup() {
emulator =
new GenericContainer<>(
DockerImageName.parse("gcr.io/cloud-spanner-emulator/emulator:latest"))
.withExposedPorts(9010)
.waitingFor(Wait.forListeningPort());
emulator.start();
}

/** Stops the emulator. */
@AfterClass
public static void cleanup() {
SpannerPool.closeSpannerPool();
if (emulator != null) {
emulator.stop();
}
}

@Test
public void testRunApplication() {
System.setProperty("spanner.emulator", "true");
System.setProperty("spanner.host", "//localhost:" + emulator.getMappedPort(9010));
SpringApplication.run(SampleApplication.class).close();
}

}

0 comments on commit aae5838

Please sign in to comment.