DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Low-Code Development: Leverage low and no code to streamline your workflow so that you can focus on higher priorities.

DZone Security Research: Tell us your top security strategies in 2024, influence our research, and enter for a chance to win $!

Launch your software development career: Dive head first into the SDLC and learn how to build high-quality software and teams.

Open Source Migration Practices and Patterns: Explore key traits of migrating open-source software and its impact on software development.

Related

  • Java Applications Log Message Analytics Using Splunk
  • Comprehensive Guide to Unit Testing Spring AOP Aspects
  • Spring Strategy Pattern Example
  • Mastering Spring: Synchronizing @Transactional and @Async Annotations With Various Propagation Strategies

Trending

  • Javac and Java Katas, Part 1: Class Path
  • OpenID Connect Flows: From Implicit to Authorization Code With PKCE and BFF
  • Documenting a Spring REST API Using Smart-doc
  • How To Use Thread.sleep() in Selenium
  1. DZone
  2. Coding
  3. Java
  4. Introducing Stalactite ORM

Introducing Stalactite ORM

A quick introduction to Stalactite ORM, from an example of how to get it as a dependency, to its integration with Spring framework.

By 
Guillaume Mary user avatar
Guillaume Mary
·
May. 10, 24 · Presentation
Like (3)
Save
Tweet
Share
2.8K Views

Join the DZone community and get the full member experience.

Join For Free

Java ORM world is very steady and few libraries exist, but none of them brought any breaking change over the last decade. Meanwhile, application architecture evolved with some trends such as Hexagonal Architecture, CQRS, Domain Driven Design, or Domain Purity. Stalactite tries to be more suitable to these new paradigms by allowing to persist any kind of Class without the need to annotate them or use external XML files: its mapping is made of method reference. 

As a benefit, you get a better view of the entity graph since the mapping is made through a fluent API that chains your entity relations, instead of spreading annotations all over entities. This is very helpful to see the complexity of your entity graph, which would impact its load as well as the memory. Moreover, since Stalactite only fetches data eagerly, we can say that what you see is what you get. Here is a very small example:

Java
 
MappingEase.entityBuilder(Country.class, Long.class)
    .mapKey(Country::getId, IdentifierPolicy.afterInsert())
    .mapOneToOne(Country::getCapital, MappingEase.entityBuilder(City.class, Long.class)
        .mapKey(City::getId, IdentifierPolicy.afterInsert())
        .map(City::getName))


First Steps

The release 2.0.0 is out for some weeks and is available as a Maven dependency, hereafter is an example with HSQLDB. For now, Stalactite is compatible with the following databases (mainly in their latest version): HSQLDB, H2, PostgreSQL, MySQL, and MariaDB.

XML
 
<dependency>
   <groupId>org.codefilarete.stalactite</groupId>
   <artifactId>orm-hsqldb-adapter</artifactId>
   <version>2.0.0</version>
</dependency>


If you're interested in a less database-vendor-dedicated module, you can use the orm-all-adapter module. Just be aware that it will bring you extra modules and extra JDBC drivers, heaving your artifact.

After getting Statactite as a dependency, the next step is to have a JDBC DataSource and pass it to a org.codefilarete.stalactite.engine.PersistenceContext:

Java
 
org.hsqldb.jdbc.JDBCDataSource dataSource= new org.hsqldb.jdbc.JDBCDataSource();
dataSource.setUrl("jdbc:hsqldb:mem:test");
dataSource.setUser("sa");
dataSource.setPassword("");
PersistenceContext persistenceContext = new PersistenceContext(dataSource, new HSQLDBDialect());


Then comes the interesting part: the mapping. Supposing you get a Country, you can quickly set up its mapping through the Fluent API, starting with the org.codefilarete.stalactite.mapping.MappingEase class as such:

Java
 
EntityPersister<Country, Long> countryPersister = MappingEase.entityBuilder(Country.class, Long.class)
    .mapKey(Country::getId, IdentifierPolicy.afterInsert())
    .map(Country::getName)
    .build(persistenceContext);


  • the afterInsert() identifier policy means that the country.id column is an auto-increment one. Two other policies exist: the beforeInsert() for identifier given by a database Sequence (for example), and the alreadyAssigned() for entities that have a natural identifier given by business rules,
  • any non-declared property is considered transient and not managed by Stalactite.

The schema can be generated with the org.codefilarete.stalactite.sql.ddl.DDLDeployer class as such (it will generate it into the PersistenceContext dataSource):

Java
 
DDLDeployer ddlDeployer = new DDLDeployer(persistenceContext);
ddlDeployer.deployDDL();


Finally, you can persist your entities thanks to the EntityPersister obtained previously, please find the example below. You might notice that you won't find JPA methods in Stalactite persister. The reason is that Stalactite is far different from JPA and doesn't aim at being compatible with it: no annotation, no attach/detach mechanism, no first-level cache, no lazy loading, and many more. Hence, the methods are quite straight to their goal:

Java
 
Country myCountry = new Country();
myCountry.setName("myCountry"); 
countryPersister.insert(myCountry); 
myCountry.setName("myCountry with a different name"); 
countryPersister.update(myCountry); 
Country loadedCountry = countryPersister.select(myCountry.getId()); 
countryPersister.delete(loadedCountry);


Spring Integration

There was a raw usage of Stalactite, meanwhile, you may be interested in its integration with Spring to benefit from the magic of its @Repository. Stalactite provides it, just be aware that it's still a work-in-progress feature. The approach to activate it is the same as for JPA: enable Stalactite repositories thanks to the @EnableStalactiteRepositories annotation on your Spring application. Then you'll declare the PersistenceContext and EntityPersister as @Bean :

Java
 
@Bean
public PersistenceContext persistenceContext(DataSource dataSource) {
    return new PersistenceContext(dataSource);
}

@Bean
public EntityPersister<Country, Long> countryPersister(PersistenceContext persistenceContext) { 
    return MappingEase.entityBuilder(Country.class, long.class) 
            .mapKey(Country::getId, IdentifierPolicy.afterInsert())
            .map(Country::getName)
            .build(persistenceContext);
}


Then you can declare your repository as such, to be injected into your services :

Java
 
@Repository
public interface CountryStalactiteRepository extends StalactiteRepository<Country, Long> {
}


As mentioned earlier, since the paradigm of Stalactite is not the same as JPA (no annotation, no attach/detach mechanism, etc), you won't find the same methods of JPA repository in Stalactite ones :

  • save : Saves the given entity, either inserting it or updating it according to its persistence states
  • saveAll : Same as the previous one, with a massive API
  • findById : Try to find an entity by its id in the database
  • findAllById : Same as the previous one, with a massive API
  • delete : Delete the given entity from the database
  • deleteAll : Same as the previous one, with a massive API

Conclusion

In these chapters we introduced the Stalactite ORM, more information about the configuration, the mapping, and all the documentation are available on the website. 

The project is open-source with the MIT license and shared through Github.

Thanks for reading, any feedback is appreciated!

HSQLDB Spring Integration Java (programming language) Spring Framework

Opinions expressed by DZone contributors are their own.

Related

  • Java Applications Log Message Analytics Using Splunk
  • Comprehensive Guide to Unit Testing Spring AOP Aspects
  • Spring Strategy Pattern Example
  • Mastering Spring: Synchronizing @Transactional and @Async Annotations With Various Propagation Strategies

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: