Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/LIBRARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ database.save(customer);
| Configure database and `Database` bean | [add-ebean-postgres-database-config.md](guides/add-ebean-postgres-database-config.md) |
| Add PostgreSQL test container support | [add-ebean-postgres-test-container.md](guides/add-ebean-postgres-test-container.md) |
| Generate DB migrations | [add-ebean-db-migration-generation.md](guides/add-ebean-db-migration-generation.md) |
| Migrate JSON APIs from Jackson core to avaje-json-core | [migrating-json-jackson-core-to-avaje-json-core.md](guides/migrating-json-jackson-core-to-avaje-json-core.md) |
| Model entity beans correctly | [entity-bean-creation.md](guides/entity-bean-creation.md) |
| Use Lombok safely with entities | [lombok-with-ebean-entity-beans.md](guides/lombok-with-ebean-entity-beans.md) |
| Write type-safe query bean queries | [writing-ebean-query-beans.md](guides/writing-ebean-query-beans.md) |
Expand Down
1 change: 1 addition & 0 deletions docs/guides/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Key guides (fetch and follow when performing the relevant task):
- Maven POM setup: https://raw.githubusercontent.com/ebean-orm/ebean/HEAD/docs/guides/add-ebean-postgres-maven-pom.md
- Database configuration: https://raw.githubusercontent.com/ebean-orm/ebean/HEAD/docs/guides/add-ebean-postgres-database-config.md
- Migrate to `Database.builder()`: https://raw.githubusercontent.com/ebean-orm/ebean/HEAD/docs/guides/migrating-to-database-builder.md
- Migrate JSON APIs from Jackson core to avaje-json-core: https://raw.githubusercontent.com/ebean-orm/ebean/HEAD/docs/guides/migrating-json-jackson-core-to-avaje-json-core.md
- Write queries with query beans: https://raw.githubusercontent.com/ebean-orm/ebean/HEAD/docs/guides/writing-ebean-query-beans.md
- Persisting and transactions: https://raw.githubusercontent.com/ebean-orm/ebean/HEAD/docs/guides/persisting-and-transactions-with-ebean.md
- Query metrics and naming: https://raw.githubusercontent.com/ebean-orm/ebean/HEAD/docs/guides/ebean-query-metrics.md
Expand Down
1 change: 1 addition & 0 deletions docs/guides/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ existing Maven project. Complete the steps in order.
| Guide | Description |
|-------|-------------|
| [Migrate to `Database.builder()`](migrating-to-database-builder.md) | Replace legacy `new DatabaseConfig()` and `DatabaseFactory.create(...)` code with `Database.builder()` and `DatabaseBuilder.build()`. Includes common rewrites, fluent builder equivalents, and manual-review cases for semi-automated upgrades |
| [Migrate JSON APIs from Jackson core to avaje-json-core](migrating-json-jackson-core-to-avaje-json-core.md) | Cut over `JsonParser`/`JsonGenerator`/`JsonFactory` usage to `JsonReader`/`JsonWriter`/`JsonStream`, including `DatabaseBuilder`/`DatabaseConfig` JSON config changes and validation checklist |

## Observability

Expand Down
91 changes: 91 additions & 0 deletions docs/guides/migrating-json-jackson-core-to-avaje-json-core.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Guide: Migrate JSON APIs from Jackson core to avaje-json-core

## Purpose

This guide covers the one-step cutover in Ebean from Jackson core JSON APIs to
avaje-json-core APIs.

Use this when upgrading code that references:

- `com.fasterxml.jackson.core.JsonParser`
- `com.fasterxml.jackson.core.JsonGenerator`
- `com.fasterxml.jackson.core.JsonFactory`

The replacement types are:

- `io.avaje.json.JsonReader`
- `io.avaje.json.JsonWriter`
- `io.avaje.json.stream.JsonStream`

---

## Breaking API changes

| Previous API | New API |
|---|---|
| `JsonParser` | `JsonReader` |
| `JsonGenerator` | `JsonWriter` |
| `JsonFactory` | `JsonStream` |
| `DatabaseBuilder.jsonFactory(...)` | `DatabaseBuilder.jsonStream(...)` |
| `DatabaseConfig.getJsonFactory()/setJsonFactory(...)` | `DatabaseConfig.getJsonStream()/setJsonStream(...)` |

---

## Typical migration rewrites

### Parser and generator signatures

```java
// before
void read(JsonParser parser)
void write(JsonGenerator generator)

// after
void read(JsonReader parser)
void write(JsonWriter generator)
```

### Database configuration

```java
// before
Database.builder().jsonFactory(factory)

// after
Database.builder().jsonStream(stream)
```

### JSON utility calls

`EJson` and `JsonContext` APIs now operate on `JsonReader` and `JsonWriter` types.
If your code was calling those APIs with Jackson core types, switch to avaje types.

---

## Dependency and module notes

- `ebean-core` no longer requires a direct `jackson-core` dependency for JSON
parsing/writing.
- `jackson-databind` remains optional for `ObjectMapper` compatibility paths.
- `ebean-jackson-mapper` remains the compatibility bridge module for mapper-based
integrations.

---

## Behavior notes to verify during upgrade

1. Parser token handling is now based on avaje `JsonReader.Token`.
2. Scalar JSON reads (for example booleans, date-time, array scalar types) should
be validated in your tests if you previously depended on Jackson token quirks.
3. If your integration uses transient assoc-many JSON mapping with ObjectMapper,
keep ObjectMapper wiring enabled.

---

## Validation checklist

1. Compile all modules that implement or consume `io.ebean.text.json` APIs.
2. Run module tests that cover JSON scalar conversion and bean JSON round-trips.
3. Confirm no remaining `com.fasterxml.jackson.core.*` imports in migrated code.
4. Keep `ObjectMapper` compatibility tests if your project depends on mapper paths.

10 changes: 4 additions & 6 deletions ebean-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,13 @@
<optional>true</optional>
</dependency>

<!-- Jackson core used internally by Ebean -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<optional>true</optional>
<groupId>io.avaje</groupId>
<artifactId>avaje-json-core</artifactId>
<version>${avaje-json-core.version}</version>
</dependency>

<!-- provided scope for JsonNode support -->
<!-- Jackson databind remains for ObjectMapper compatibility paths -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
Expand Down
16 changes: 8 additions & 8 deletions ebean-api/src/main/java/io/ebean/DatabaseBuilder.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.ebean;

import com.fasterxml.jackson.core.JsonFactory;
import io.avaje.json.stream.JsonStream;
import io.ebean.annotation.*;
import io.ebean.cache.ServerCachePlugin;
import io.ebean.config.*;
Expand Down Expand Up @@ -360,18 +360,18 @@ default DatabaseBuilder slowQueryListener(SlowQueryListener slowQueryListener) {
DatabaseBuilder putServiceObject(Object configObject);

/**
* Set the Jackson JsonFactory to use.
* Set the JsonStream to use.
* <p>
* If not set a default implementation will be used.
*/
default DatabaseBuilder jsonFactory(JsonFactory jsonFactory) {
return setJsonFactory(jsonFactory);
default DatabaseBuilder jsonStream(JsonStream jsonStream) {
return setJsonStream(jsonStream);
}

/**
* @deprecated migrate to {@link #jsonFactory(JsonFactory)}.
* @deprecated migrate to {@link #jsonStream(JsonStream)}.
*/
DatabaseBuilder setJsonFactory(JsonFactory jsonFactory);
DatabaseBuilder setJsonStream(JsonStream jsonStream);

/**
* Set the JSON format to use for DateTime types.
Expand Down Expand Up @@ -2254,11 +2254,11 @@ interface Settings extends DatabaseBuilder {
boolean isAutoLoadModuleInfo();

/**
* Return the Jackson JsonFactory to use.
* Return the JsonStream to use.
* <p>
* If not set a default implementation will be used.
*/
JsonFactory getJsonFactory();
JsonStream getJsonStream();

/**
* Get the clock used for setting the timestamps (e.g. @UpdatedTimestamp) on objects.
Expand Down
4 changes: 2 additions & 2 deletions ebean-api/src/main/java/io/ebean/config/ClassLoadConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public boolean isJacksonAnnotationsPresent() {
}

public boolean isJacksonCorePresent() {
return isPresent("com.fasterxml.jackson.core.JsonParser");
// Legacy method name retained for compatibility; now checks avaje JSON core.
return isPresent("io.avaje.json.JsonReader");
}

/**
Expand Down Expand Up @@ -158,4 +159,3 @@ ClassLoader getClassLoader() {
}
}
}

12 changes: 6 additions & 6 deletions ebean-api/src/main/java/io/ebean/config/DatabaseConfig.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.ebean.config;

import com.fasterxml.jackson.core.JsonFactory;
import io.avaje.config.Config;
import io.avaje.json.stream.JsonStream;
import io.ebean.*;
import io.ebean.annotation.MutationDetection;
import io.ebean.annotation.PersistBatch;
Expand Down Expand Up @@ -420,7 +420,7 @@ public class DatabaseConfig implements DatabaseBuilder.Settings {
* The default PersistenceContextScope used if one is not explicitly set on a query.
*/
private PersistenceContextScope persistenceContextScope = PersistenceContextScope.TRANSACTION;
private JsonFactory jsonFactory;
private JsonStream jsonStream;
private boolean localTimeWithNanos;
private boolean durationWithNanos;
private int maxCallStack = 5;
Expand Down Expand Up @@ -631,13 +631,13 @@ private String serviceObjectKey(Class<?> cls) {
}

@Override
public JsonFactory getJsonFactory() {
return jsonFactory;
public JsonStream getJsonStream() {
return jsonStream;
}

@Override
public DatabaseConfig setJsonFactory(JsonFactory jsonFactory) {
this.jsonFactory = jsonFactory;
public DatabaseConfig setJsonStream(JsonStream jsonStream) {
this.jsonStream = jsonStream;
return this;
}

Expand Down
28 changes: 14 additions & 14 deletions ebean-api/src/main/java/io/ebean/service/SpiJsonService.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.ebean.service;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import io.avaje.json.JsonReader;
import io.avaje.json.JsonReader.Token;
import io.avaje.json.JsonWriter;

import java.io.IOException;
import java.io.Reader;
Expand Down Expand Up @@ -32,12 +32,12 @@ public interface SpiJsonService extends BootstrapService {
/**
* Write the nested Map/List as json to the jsonGenerator.
*/
void write(Object object, JsonGenerator jsonGenerator) throws IOException;
void write(Object object, JsonWriter jsonGenerator) throws IOException;

/**
* Write the collection as json array to the jsonGenerator.
*/
void writeCollection(Collection<Object> collection, JsonGenerator jsonGenerator) throws IOException;
void writeCollection(Collection<Object> collection, JsonWriter jsonGenerator) throws IOException;

/**
* Parse the json and return as a Map additionally specifying if the returned map should
Expand All @@ -61,17 +61,17 @@ public interface SpiJsonService extends BootstrapService {
Map<String, Object> parseObject(Reader reader) throws IOException;

/**
* Parse the json and return as a Map taking a JsonParser.
* Parse the json and return as a Map taking a JsonReader.
*/
Map<String, Object> parseObject(JsonParser parser) throws IOException;
Map<String, Object> parseObject(JsonReader parser) throws IOException;

/**
* Parse the json and return as a Map taking a JsonParser and a starting token.
* Parse the json and return as a Map taking a JsonReader and a starting token.
* <p>
* Used when the first token is checked to see if the value is null prior to calling this.
* </p>
*/
Map<String, Object> parseObject(JsonParser parser, JsonToken token) throws IOException;
Map<String, Object> parseObject(JsonReader parser, Token token) throws IOException;

/**
* Parse the json and return as a modify aware List.
Expand All @@ -89,14 +89,14 @@ public interface SpiJsonService extends BootstrapService {
List<Object> parseList(Reader reader) throws IOException;

/**
* Parse the json and return as a List taking a JsonParser.
* Parse the json and return as a List taking a JsonReader.
*/
List<Object> parseList(JsonParser parser) throws IOException;
List<Object> parseList(JsonReader parser) throws IOException;

/**
* Parse the json returning as a List taking into account the current token.
*/
<T> List<T> parseList(JsonParser parser, JsonToken currentToken) throws IOException;
<T> List<T> parseList(JsonReader parser, Token currentToken) throws IOException;

/**
* Parse the json and return as a List or Map.
Expand All @@ -111,7 +111,7 @@ public interface SpiJsonService extends BootstrapService {
/**
* Parse the json and return as a List or Map.
*/
Object parse(JsonParser parser) throws IOException;
Object parse(JsonReader parser) throws IOException;

/**
* Parse the json returning a Set that might be modify aware.
Expand All @@ -121,5 +121,5 @@ public interface SpiJsonService extends BootstrapService {
/**
* Parse the json returning as a Set taking into account the current token.
*/
<T> Set<T> parseSet(JsonParser parser, JsonToken currentToken) throws IOException;
<T> Set<T> parseSet(JsonReader parser, Token currentToken) throws IOException;
}
Loading
Loading