Building IoT Time-Series Applications With Java and Apache IoTDB
Apache IoTDB targets device-oriented time-series workloads. Eclipse JNoSQL 1.1.18 lets Java devs use it with TimeSeriesTemplate and Jakarta Data repositories.
Join the DZone community and get the full member experience.
Join For FreeApache IoTDB is well-suited for environments where time-series data from connected devices and industrial systems is generated continuously and requires efficient querying. Typical use cases include monitoring temperature, pressure, vibration, energy usage, machine status, and device telemetry. This approach also applies to manufacturing, smart infrastructure, fleet monitoring, utilities, and edge computing.
IoTDB stands out for its focus on large-scale time-series workloads from devices and industrial systems. It is purpose-built for high-frequency data ingestion, historical analysis, and time-based queries. This makes it ideal for applications that require insight into both the current state and historical trends of devices or processes.
Why Apache IoTDB Matters
Apache IoTDB excels at managing large volumes of device-generated data over time. It addresses issues beyond storage, such as continuous data ingestion, efficient organization by device and timestamp, and fast queries for both recent and historical values. This makes IoTDB well-suited for systems with temporal, device-oriented data models.
Common use cases include industrial IoT, smart factories, energy monitoring, connected vehicles, building automation, predictive maintenance, and edge computing. For example, manufacturers can track machinery data, utilities can analyze energy consumption across many meters, and fleet operators can monitor location and engine telemetry. In each scenario, IoTDB enables applications to determine current status, review device behavior over time, and detect measurements outside expected ranges.
Hands-On: Java With Apache IoTDB
We will build a simple Java application using Apache IoTDB. For simplicity, IoTDB will run locally in Docker.
docker run -d \
--name iotdb-instance \
-p 6667:6667 \
-e dn_rpc_address=0.0.0.0 \
apache/iotdb:2.0.11-standalone
Next, create the database using IoTDB’s Table SQL dialect:
docker exec -it iotdb-instance \
/iotdb/sbin/start-cli.sh \
-h 127.0.0.1 \
-p 6667 \
-u root \
-pw root \
-sql_dialect table \
-e "CREATE DATABASE IF NOT EXISTS jnosql"
For this local example, we use the default root/root credentials and disable client redirection. These settings are suitable for single-node development only. In production, use secure credentials and configure redirection based on your IoTDB cluster topology.
Configuring the Application
Next, configure the connection in microprofile-config.properties:
jnosql.timeseries.database=jnosql
jnosql.iotdb.host=localhost
jnosql.iotdb.port=6667
jnosql.iotdb.username=root
jnosql.iotdb.password=root
jnosql.iotdb.enable.redirection=false
Eclipse JNoSQL is built on Jakarta APIs such as CDI, JSON-B, and Eclipse MicroProfile Config. These APIs are supported by popular runtimes including Helidon, Quarkus, Open Liberty, and other Jakarta EE-compatible environments.
Then add the Apache IoTDB driver:
<dependency>
<groupId>org.eclipse.jnosql.databases</groupId>
<artifactId>jnosql-iotdb</artifactId>
<version>${jnosql.version}</version>
</dependency>
Modeling Sensor Data
A sensor-oriented model aligns well with IoTDB:
@Entity
public class SensorReading {
@Id
private Instant id;
@Column
private String sensor;
@Column
private double temperature;
@Column
private double humidity;
// constructors, getters, and setters
}
The Instant field records the timestamp of the reading. The other fields capture the measurements at that time.
The entity can also be exposed through Jakarta Data:
@Repository
public interface SensorReadingRepository
extends BasicRepository<SensorReading, Instant> {
List<SensorReading> findBySensorOrderByIdDesc(
String sensor,
Limit limit);
}
Using TimeSeriesTemplate
With the infrastructure in place, insert several readings and retrieve both the latest value and recent history:
"sensor-01",
22.1,
46.5
);
var latestReading = new SensorReading(
Instant.parse("2026-09-20T10:15:00Z"),
"sensor-01",
23.6,
48.2
);
try (SeContainer container =
SeContainerInitializer.newInstance().initialize()) {
TimeSeriesTemplate template =
container.select(TimeSeriesTemplate.class).get();
template.insert(firstReading);
template.insert(secondReading);
template.insert(latestReading);
var currentReading = template
.select(SensorReading.class)
.where("sensor")
.eq("sensor-01")
.orderBy("id")
.desc()
.limit(1)
.singleResult();
System.out.println(
"Current sensor reading: " + currentReading
);
var history = template
.select(SensorReading.class)
.where("sensor")
.eq("sensor-01")
.orderBy("id")
.desc()
.skip(1)
.limit(10)
.result();
System.out.println("Recent sensor history:");
history.forEach(System.out::println);
}
}
}
The first query answers a common IoT question: what is the latest reading from this sensor? The second retrieves its recent history, excluding the latest observation.
Using Jakarta Data
The same use case can be implemented using the repository:
public class App2 {
public static void main(String[] args) {
var firstReading = new SensorReading(
Instant.parse("2026-09-20T08:00:00Z"),
"sensor-01",
21.4,
45.0
);
var secondReading = new SensorReading(
Instant.parse("2026-09-20T09:00:00Z"),
"sensor-01",
22.1,
46.5
);
var latestReading = new SensorReading(
Instant.parse("2026-09-20T10:15:00Z"),
"sensor-01",
23.6,
48.2
);
try (SeContainer container =
SeContainerInitializer.newInstance().initialize()) {
SensorReadingRepository repository =
container.select(SensorReadingRepository.class).get();
repository.save(firstReading);
repository.save(secondReading);
repository.save(latestReading);
var currentReading = repository
.findBySensorOrderByIdDesc(
"sensor-01",
Limit.of(1)
)
.stream()
.findFirst();
System.out.println(
"Current sensor reading: " + currentReading
);
var history = repository
.findBySensorOrderByIdDesc(
"sensor-01",
Limit.range(2, 10)
);
System.out.println("Recent sensor history:");
history.forEach(System.out::println);
}
}
}
Both approaches model the domain in terms of latest state and historical observations. This is where a time-series database like Apache IoTDB is more effective than using a general-purpose database with timestamps as regular fields.
Why Apache IoTDB Is More Than Sensor Storage
While Apache IoTDB is often associated with IoT, its capabilities go well beyond basic sensor data storage. It excels when organizations must manage large volumes of device-centric data over time while retaining relationships among measurements, devices, and timestamps. As a result, IoTDB is valuable for industrial systems, utilities, transportation, smart infrastructure, manufacturing, and edge computing.
For example, in predictive maintenance, a machine may continuously report vibration, temperature, pressure, energy consumption, and operating condition. The true value is not only found in the latest readings, but in studying how these measurements change together over time. Maintenance systems may compare recent data with historical trends, spot anomalies before failures, or correlate changes across multiple devices. This requires more than simple sensor data storage.
This approach also benefits energy systems, where smart meters, solar panels, batteries, and grid equipment generate continuous measurement streams that require time-based analysis. In transportation, vehicles produce ongoing data such as speed, location, fuel consumption, battery status, and engine telemetry. Similarly, smart buildings rely on time-series data from HVAC systems, occupancy sensors, and energy meters.
IoTDB is especially effective when system architecture is organized around devices and their measurements. It can serve as the historical data layer for operational systems, while other technologies manage transactional or business information. For example, a relational database might store details about a machine, its owner, contracts, or maintenance schedules, while IoTDB manages the extensive measurement data the machine generates.
This separation lets enterprise applications treat telemetry as a primary workload, rather than forcing high-frequency device data into models meant for business entities and transactions.
Conclusion
Apache IoTDB is a strong fit for applications that need to ingest and analyze device-generated data over time, especially in IoT, industrial, energy, and edge scenarios. With Eclipse JNoSQL 1.1.18, Java developers can access these capabilities through familiar Jakarta APIs, keeping the application model consistent while still leveraging IoTDB’s time-series specialization.
Opinions expressed by DZone contributors are their own.
Comments