Skip to content
Merged
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
19 changes: 17 additions & 2 deletions site/docs/releases/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,32 @@ sidebar_position: 1

List of upcoming and historic changes to Spring Cloud Oracle.

### Next, TBD
### 2.0.1, TBD

#### Database Starters

- Upgrade third-party dependencies
- OpenTelemetry with Oracle AI Database documentation:
- Added starter usage and configuration guidance for `spring-boot-starter-oracle-otel`
- Documented how Oracle JDBC tracing spans flow into OpenTelemetry backends
- Oracle Spatial documentation and sample:
- Added starter documentation for GeoJSON-first `SDO_GEOMETRY` development
- Added the spatial sample reference covering the REST-based landmarks example

#### Spring Cloud Stream Binder for TxEventQ

- Upgrade third-party dependencies

#### Spring Cloud OCI

- Upgrade third-party dependencies
- OCI Object Storage `WritableResource` support:
- The OCI Object Storage Spring `Resource` now also implements `WritableResource`, allowing object uploads through `getOutputStream()`
- The Object Storage sample now demonstrates Spring `Resource`, `WritableResource`, and direct `Storage` API round trips for objects and bucket lifecycle operations
- The Object Storage documentation now includes `WritableResource` usage in addition to the existing `Resource` examples


### 2.0.0, March TBD
### 2.0.0, March 31st

The 2.0.0 adds support for Spring Boot 4 and Spring Framework 7, and includes numerous third party dependency updates.

Expand Down
2 changes: 1 addition & 1 deletion site/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const config: Config = {
},
{
type: 'docsVersionDropdown',
versions: ['current', '2.0.0' ]
versions: ['current', '2.0.1', '2.0.0' ]
},
{
href: 'https://github.com/oracle/spring-cloud-oracle',
Expand Down
2 changes: 1 addition & 1 deletion site/versioned_docs/version-2.0.0/releases/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ sidebar_position: 1

List of upcoming and historic changes to Spring Cloud Oracle.

### 2.0.0, March TBD
### 2.0.0, March 31st

The 2.0.0 adds support for Spring Boot 4 and Spring Framework 7, and includes numerous third party dependency updates.

Expand Down
8 changes: 8 additions & 0 deletions site/versioned_docs/version-2.0.1/database/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Oracle AI Database Starters",
"position": 2,
"link": {
"type": "generated-index",
"description": "Spring Boot starters for Oracle AI Database connections, messaging, JSON features, and Kafka-compatible TxEventQ access."
}
}
131 changes: 131 additions & 0 deletions site/versioned_docs/version-2.0.1/database/aq-jms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
title: AQ/JMS
sidebar_position: 3
---

# Spring JMS with TxEventQ

The AQ/JMS starter provides Spring Boot support for Oracle Transactional Event Queues (TxEventQ) as a [Spring JMS provider](https://spring.io/guides/gs/messaging-jms).

## Dependency Coordinates

To use Oracle AI Database for JMS, include the oracle-spring-boot-starter-aqjms and spring-boot-starter-jdbc dependencies in your project:

```xml
<dependency>
<groupId>com.oracle.database.spring</groupId>
<artifactId>oracle-spring-boot-starter-aqjms</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
```

## Database Permissions

The database JMS user should have at least the following permissions to produce and consume messages with Oracle AI Database:

```sql
grant aq_user_role to testuser;
grant execute on dbms_aq to testuser;
grant execute on dbms_aqadm to testuser;
grant execute ON dbms_aqin TO testuser;
grant execute ON dbms_aqjms TO testuser;
```

## Create a JMS Queue or Topic

JMS applications must have an existing queue or topic. You may create this from your application code, or do so with a PL/SQL statement. The following snippet creates a JMS queue named `MY_JMS_QUEUE` in the `TESTUSER` schema:

```sql
begin
dbms_aqadm.create_transactional_event_queue(
queue_name => 'TESTUSER.MY_JMS_QUEUE',
-- False -> JMS Queue. True -> JMS Topic
multiple_consumers => false
);

-- start the TEQ
dbms_aqadm.start_queue(
queue_name => 'TESTUSER.MY_JMS_QUEUE'
);
end;
/
```

## Database Connection

JMS uses a standard Spring Boot datasource JDBC connection. Oracle AI Database JMS producers and consumers will use autowired Spring JDBC datasource:

```yaml
spring:
datasource:
username: ${USERNAME}
password: ${PASSWORD}
url: ${JDBC_URL}
driver-class-name: oracle.jdbc.OracleDriver
type: oracle.ucp.jdbc.PoolDataSourceImpl
oracleucp:
initial-pool-size: 1
min-pool-size: 1
max-pool-size: 30
connection-pool-name: TxEventQSample
connection-factory-class-name: oracle.jdbc.pool.OracleDataSource
```

## Produce and consume messages

You can use Spring JMS abstractions like `JMSTemplate`, `JMSListener`, and `JMSClient` in your Spring Boot applications with Oracle AI Database.

### Producer Example with `JMSTemplate`

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.jms.core.JmsTemplate;

@Service
public class Producer {

private static final Logger log = LoggerFactory.getLogger(Producer.class);

JmsTemplate jmsTemplate;

@Value("${txeventq.topic.name}")
private String topic;

public Producer(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}

public void sendMessageToTopic(String message)
{
jmsTemplate.convertAndSend(topic,message);
log.info("Sending message: {} to topic {}", message, topic);
}
}
```

### Consumer Example with `@JMSListener`

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;

@Service
public class Consumer {

private static final Logger log = LoggerFactory.getLogger(Consumer.class);

@JmsListener(destination = "${txeventq.topic.name}")
public void receiveMessage(String message) {
log.info("Received message: {}", message);
}
}
```
95 changes: 95 additions & 0 deletions site/versioned_docs/version-2.0.1/database/json-collections.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: JSON Collections and Duality Views
sidebar_position: 4
---

# JSON Collections and Duality Views

The JSON starter provides dependencies and utilities for working with Oracle AI Database JSON data, including the JSON data type, JSON Relational Duality Views, and [Oracle's efficient serialized JSON format, OSON](https://medium.com/db-one/a-deep-dive-into-binary-json-formats-oson-e3190e5e9eb0).

## Dependency Coordinates

```xml
<dependency>
<groupId>com.oracle.database.spring</groupId>
<artifactId>oracle-spring-boot-starter-json-collections</artifactId>
</dependency>
```

## JSONB Conversion

The `JSONB` bean converts Java objects to and from OSON using `fromOSON` and `toOSON`. `InputStream`, `JsonParser`, `ByteBuffer`, and `byte[]` are supported as OSON input types.

```java
@Autowired
JSONB jsonb;

// byte[], JsonParser, and ByteBuffer also supported as input types
Student student = jsonb.fromOSON(inputStream, Student.class);
byte[] bytes = jsonb.toOSON(student);
```

## Mapping OSON Rows

`JSONBRowMapper` converts OSON database columns to Java objects:

```java
RowMapper<Student> rowMapper = new JSONBRowMapper<>(this.jsonb, Student.class);

List<Student> students = jdbcTemplate.query(con -> {
PreparedStatement ps = con.prepareStatement("""
select * from students_dv v
where v.data.first_name = ?
and v.data.last_name = ?
""");
ps.setString(1, firstName);
ps.setString(2, lastName);
return ps;
}, rowMapper);
```

By default, the first column is selected as the JSON column. You may customize this when instantiating the `JSONBRowMapper`:

```java
RowMapper<Student> rowMapper = new JSONBRowMapper<>(
this.jsonb,
Student.class,
2 // column number of OSON data
);
```

## OSON Kafka Serializers

Spring Boot applications that mix OKafka APIs with OSON data may benefit from using OSON as the message serialization format. This is particularly useful when you're already using OSON as the storage format - messages sent as OSON may be inserted into a table using Oracle's JSON type without any further serialization.

The `OSONKafkaSerializationFactory` bean provides factory methods for kafka-java serializers and deserializers that allow you to send events in OSON format.

### Consumer Deserializer

```java
@Autowired
private OSONKafkaSerializationFactory osonKafkaSerializationFactory;

Deserializer<String> keyDeserializer = new StringDeserializer();
Deserializer<Sensor> valueDeserializer = osonKafkaSerializationFactory.createDeserializer(Sensor.class);
return new KafkaConsumer<>(props, keyDeserializer, valueDeserializer);
```

### Producer Serializer

```java
@Autowired
private OSONKafkaSerializationFactory osonKafkaSerializationFactory;


Serializer<String> keySerializer = new StringSerializer();
Serializer<Sensor> valueSerializer = osonKafkaSerializationFactory.createSerializer();
return new KafkaProducer<>(props, keySerializer, valueSerializer);
```

The Kafka/OSON classes will only be autowired if `kafka-clients` is on the classpath.

## Learn by example

- [Spring JDBC with JSON Relational Duality Views](https://github.com/oracle/spring-cloud-oracle/tree/main/database/starters/oracle-spring-boot-starter-samples/oracle-spring-boot-sample-json-duality)
- [JSON Event Streaming](https://github.com/oracle/spring-cloud-oracle/tree/main/database/starters/oracle-spring-boot-starter-samples/oracle-spring-boot-sample-json-events)
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: JSON Relational Duality View Builder
sidebar_position: 5
---

Oracle AI Database’s JSON Relational Duality Views (or simply duality views) let you treat relational tables and JSON documents as two sides of the same model: build your relational schema, and use comprehensive, normalized JSON documents on top.

The JSON Relational Duality View builder allows developers to automatically generate duality view DDL from plain Java classes or JPA entities.

## Dependency Coordinates

```xml
<dependency>
<groupId>com.oracle.database.spring</groupId>
<artifactId>oracle-spring-boot-json-relational-duality-views</artifactId>
</dependency>
```

## Enable Duality View Builder with package scanning

The Duality View builder must be explicitly enabled through package scanning.

```java
@SpringBootApplication(scanBasePackages = {
"com.example",
// Enable the duality view event listener
"com.oracle.spring.json.duality.builder"
})
public class Application { // main class }
```

## Annotations for Duality View Generation

The custom `@JsonRelationalDualityView `annotation denotes that a Java class (usually a JPA entity) should have a duality view generated from its structure. Fields and annotations on the class are used to dynamically construct the duality view.

You may apply this annotation to any nested classes to create nested objects in your view.

The custom `@AccessMode` annotation is used to specify insert, update, and delete functionality on view objects. By default, read-only access is granted in the generated view.

The jakarta.json `@JsonbProperty("_id")` annotation is recommended for any root ID fields: duality views use the _id field in JSON documents for the root primary key. It may also be used to rename class fields in the resulting duality view.

The jakarta.json `@JsonbTransient` annotation is recommended to skip specific fields in the generated duality view. This is necessary for cyclic objects.

## Annotate Java Classes or JPA Entities

Any Java class or JPA entity annotated with `@JsonRelationalDualityView` on the Spring Boot classpath scan will have a duality view generated from it's metadata.

For example, the `Actor` entity is annotated with `@JsonRelationalDualityView`, and a duality view generated at startup time, but after Hibernate runs:

```java
@Entity
@Table(name = "actor")
@JsonRelationalDualityView(accessMode = @AccessMode(insert = true))
public class Actor {
@JsonbProperty(_ID_FIELD)
@Id
@Column(name = "actor_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long actorId;

// other entity fields, Movies, Directors, etc.
```

A resulting duality view definition from this JPA entity may look like this:

```sql
create force editionable json relational duality view actor_dv as actor @insert {
_id : actor_id
firstName : first_name
lastName : last_name
movies : movie_actor @insert [ {
movie @unnest @insert {
_id : movie_id
title
releaseYear : release_year
genre
director @insert @link (from : [director_id]) {
_id : director_id
firstName : first_name
lastName : last_name
}
}
} ]
}
```

## Control generation through Spring properties

We can configure duality view generation in Spring JPA settings. The same ddl-auto values for JPA can be used for duality views:

```yaml
spring:
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
dv:
# create-drop views after JPA ddl-auto is complete
ddl-auto: create-drop
# Print JSON Relational Duality Views to the console
show-sql: true
```

## Learn By Example

- [JPA Duality View Builder Sample with Actor, Movie, and Director entities](https://github.com/anders-swanson/oracle-database-code-samples/tree/main/json/jpa-duality-views)
Loading
Loading