The Java ecosystem is built on a foundation of robustness, type safety, and enterprise-grade stability. Yet, for decades, connecting Java applications to a database has involved a series of painful compromises. Developers are forced to navigate the immense complexity of Object-Relational Mapping (ORM) frameworks like Hibernate, write verbose and error-prone JDBC boilerplate, or abandon type safety altogether for the promise of NoSQL flexibility.
StatelyDB provides a modern data platform that aligns perfectly with the principles of modern Java development. Our schema-first workflow and powerful code generation eliminate the ceremony and complexity, allowing you to work with clean, simple Plain Old Java Objects (POJOs). Stop fighting the impedance mismatch between your objects and your database, and start building reliable, scalable applications faster.
If you are a Java developer, you have felt this pain. The simple act of persisting an object requires navigating a landscape of difficult trade-offs:
You adopt JPA and Hibernate, only to spend your time wrestling with XML configuration or annotation soup, debugging lazy-loading exceptions, and tuning performance to avoid the dreaded "N+1 selects" problem. The framework, meant to help, becomes a project in itself.
You opt for direct control with JDBC, but now you are writing hundreds of lines of repetitive try-with-resources blocks, manually mapping ResultSet columns to object fields, and carefully handling SQLException. It is a recipe for bugs and burnout.
You use a NoSQL database like MongoDB or DynamoDB to gain flexibility, but your code is now littered with Document objects or Map<String, Object>. You lose the compile-time safety that is one of Java's greatest strengths and must write extensive validation and mapping code.
Changing your data model is a high-stakes, operational challenge. You depend on external tools like Flyway or Liquibase to manage schema migrations, which often require downtime and introduce significant deployment risk.
StatelyDB was designed to deliver a developer experience that feels native to Java. It is simple, type-safe, and removes the friction between your application and your data.
Your data model is the single source of truth. You define it once using our simple, TypeScript-based Elastic Schema™. This schema serves as a language-agnostic blueprint for your entire data layer.
import { itemType, string, uuid } from "@stately-cloud/schema";
/** A user of our new application. */
itemType("User", {
keyPath: "/user-:id",
fields: {
id: { type: uuid, initialValue: "uuid" },
name: { type: string },
email: { type: string },
},
});Run a single command to generate a Java package with clean POJOs for every item in your schema. There are no JPA annotations, no XML files, and no dependency on a heavy framework. Just simple, idiomatic Java classes.
stately schema generate \
--language java \
--schema-id <your-schema-id> \
./src/main/java/com/yourcompany/statelyThis command generates a com.yourcompany.stately package you can import and use immediately.
package com.yourcompany.stately;
import java.util.UUID;
public class User {
public UUID id;
public String name;
public String email;
// ...getters and setters...
}Using the generated POJOs, interacting with StatelyDB is as straightforward as working with any other Java object. Our SDK provides a clean, builder-style API that is a pleasure to use.
Compare the simplicity of StatelyDB to the ceremony required by a typical ORM or JDBC.
StatelyDB: Simple and Type-Safe
import com.yourcompany.stately.User;
import cloud.stately.sdk.StatelyClient;
public class UserService {
public User createUser(StatelyClient client, String name, String email) {
// Just instantiate and put a native Java object.
User userToCreate = new User();
userToCreate.name = name;
userToCreate.email = email;
User createdUser = client.put(userToCreate, User.class);
System.out.println("Created user with ID: " + createdUser.id);
return createdUser;
}
}Typical Hibernate/JPA: Annotations and Session Management
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private String email;
// ...getters, setters, constructors...
}
public class UserService {
public User createUser(SessionFactory sessionFactory, String name, String email) {
User user = new User();
user.setName(name);
user.setEmail(email);
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
}
return user;
}
}With StatelyDB, the code is simpler, the intent is clearer, and there is no complex framework to manage. You focus on your business logic, not on database plumbing.
When your business requirements change, you can adapt your data model without the fear and complexity of traditional migrations. Simply update your schema.ts file, add a migration command, and regenerate your Java POJOs. StatelyDB's Elastic Schema ensures your changes are always backwards and forwards compatible. You can deploy a new version of your Java service with confidence, knowing it will not break existing clients or require a maintenance window.
StatelyDB was designed to deliver a developer experience that feels native to Java. It is simple, type-safe, and removes the friction between your application and your data.
Your data model is the single source of truth. You define it once using our simple, TypeScript-based Elastic Schema™. This schema serves as a language-agnostic blueprint for your entire data layer.
import { itemType, string, uuid } from "@stately-cloud/schema";
/** A user of our new application. */
itemType("User", {
keyPath: "/user-:id",
fields: {
id: { type: uuid, initialValue: "uuid" },
name: { type: string },
email: { type: string },
},
});Run a single command to generate a Java package with clean POJOs for every item in your schema. There are no JPA annotations, no XML files, and no dependency on a heavy framework. Just simple, idiomatic Java classes.
stately schema generate \
--language java \
--schema-id <your-schema-id> \
./src/main/java/com/yourcompany/statelyThis command generates a com.yourcompany.stately package you can import and use immediately.
package com.yourcompany.stately;
import java.util.UUID;
public class User {
public UUID id;
public String name;
public String email;
// ...getters and setters...
}Using the generated POJOs, interacting with StatelyDB is as straightforward as working with any other Java object. Our SDK provides a clean, builder-style API that is a pleasure to use.
Compare the simplicity of StatelyDB to the ceremony required by a typical ORM or JDBC.
StatelyDB: Simple and Type-Safe
import com.yourcompany.stately.User;
import cloud.stately.sdk.StatelyClient;
public class UserService {
public User createUser(StatelyClient client, String name, String email) {
// Just instantiate and put a native Java object.
User userToCreate = new User();
userToCreate.name = name;
userToCreate.email = email;
User createdUser = client.put(userToCreate, User.class);
System.out.println("Created user with ID: " + createdUser.id);
return createdUser;
}
}Typical Hibernate/JPA: Annotations and Session Management
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private String email;
// ...getters, setters, constructors...
}
public class UserService {
public User createUser(SessionFactory sessionFactory, String name, String email) {
User user = new User();
user.setName(name);
user.setEmail(email);
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
session.save(user);
session.getTransaction().commit();
}
return user;
}
}With StatelyDB, the code is simpler, the intent is clearer, and there is no complex framework to manage. You focus on your business logic, not on database plumbing.
When your business requirements change, you can adapt your data model without the fear and complexity of traditional migrations. Simply update your schema.ts file, add a migration command, and regenerate your Java POJOs. StatelyDB's Elastic Schema ensures your changes are always backwards and forwards compatible. You can deploy a new version of your Java service with confidence, knowing it will not break existing clients or require a maintenance window.
Ready to build with a database designed for the modern Java stack?
Follow our Getting Started Guide to create your account, store, and schema.
Add the Java SDK dependency to your pom.xml or build.gradle file.
Generate your Java POJOs as shown above.
Initialize the client and start building.
It is that simple