<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Guillaume Mary</title>
    <description>The latest articles on DEV Community by Guillaume Mary (@guiommary).</description>
    <link>https://dev.to/guiommary</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F685427%2F43de5ca3-d940-4992-b9b4-94531d4a439e.png</url>
      <title>DEV Community: Guillaume Mary</title>
      <link>https://dev.to/guiommary</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guiommary"/>
    <language>en</language>
    <item>
      <title>A simplified definition of an ORM</title>
      <dc:creator>Guillaume Mary</dc:creator>
      <pubDate>Fri, 29 Aug 2025 06:25:16 +0000</pubDate>
      <link>https://dev.to/codefilarete/a-simplified-definition-of-an-orm-4pl</link>
      <guid>https://dev.to/codefilarete/a-simplified-definition-of-an-orm-4pl</guid>
      <description>&lt;p&gt;"Back to school" is here... (at least in France), but have you ever tried to fit a whole school into an Excel file? 🤔😄&lt;/p&gt;

&lt;p&gt;While the question seems strange, this is exactly what an &lt;strong&gt;ORM (Object-Relational Mapping)&lt;/strong&gt; aims to do.&lt;/p&gt;

&lt;p&gt;Imagine you're a principal and you have to enter all the students, their parents, teachers, subjects, classes, etc., and most importantly, &lt;strong&gt;all the relationships that link them&lt;/strong&gt;, into your spreadsheet. It's quite a puzzle!&lt;/p&gt;

&lt;p&gt;If we were to create an application to help our principal, &lt;strong&gt;the ORM would be there to help us distribute these concepts (student, parent, teachers...) into the sheets of the Excel file&lt;/strong&gt; (more specifically, into the tables of the database). It would then allow us to access them to find out if H.Potter has a Math class on Tuesday from 2 p.m. to 3 p.m., or to retrieve professor McGonagall's students...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The ORM is therefore there to store the elements (student, parent, etc.) and especially their relations&lt;/strong&gt;, while allowing them to be easily retrieved. It's an essential building block in applications that &lt;strong&gt;saves developers a lot of time&lt;/strong&gt;... but it remains tricky to master. The puzzle it saves you from often comes at the cost of behaviors that are not very optimal for your application's specific case, as &lt;strong&gt;an ORM must be generic&lt;/strong&gt;, capable of handling any domain: cooking recipes and their ingredients, cars and customers of a dealership, medical records of hospital patients, etc.&lt;/p&gt;

&lt;p&gt;And clearly, this genericity is not easy to develop since the ORM's algorithms must allow it to be applicable everywhere, with the least amount of effort possible for developers.&lt;/p&gt;

&lt;p&gt;This is why you're not hearing about &lt;a href="https://www.codefilarete.org/" rel="noopener noreferrer"&gt;Stalactite&lt;/a&gt; right now! 😛 It's going through a difficult phase to account for all possible scenarios... so it's long and complicated! The next version will bring compatibility with Spring-Data, putting it on par with JPA / Hibernate for ease of integration.&lt;/p&gt;

&lt;p&gt;So if you want to give me a little encouragement and support me in this endeavor, don't hesitate to "star" &lt;a href="https://github.com/codefilarete/stalactite" rel="noopener noreferrer"&gt;the GitHub repo&lt;/a&gt;. It's an important indicator of its popularity and my morale! 😄&lt;/p&gt;

&lt;p&gt;Strength and honor to all volunteer maintainers of open-source projects! 💪👍&lt;/p&gt;

</description>
      <category>orm</category>
      <category>java</category>
      <category>database</category>
      <category>sql</category>
    </item>
    <item>
      <title>There is no difference between technical debt and washing up</title>
      <dc:creator>Guillaume Mary</dc:creator>
      <pubDate>Sat, 25 Jan 2025 08:51:11 +0000</pubDate>
      <link>https://dev.to/codefilarete/there-is-no-difference-between-technical-debt-and-washing-up-2l0c</link>
      <guid>https://dev.to/codefilarete/there-is-no-difference-between-technical-debt-and-washing-up-2l0c</guid>
      <description>&lt;ul&gt;
&lt;li&gt;We always have better things to do than deal with them: Implement new features or watch a series / go out with friends / play sports&lt;/li&gt;
&lt;li&gt;When they pile up, they are harmful: dirty dishes attract insects, technical debt generates bugs&lt;/li&gt;
&lt;li&gt;They have a snowball effect: new features are increasingly complicated to implement, so we hurry up and generate even more debt.&lt;/li&gt;
&lt;li&gt;If you want to cook while there are dishes in the sink, you don't dare to do the day's dishes, so you leave them in the sink too&lt;/li&gt;
&lt;li&gt;Only people who live with them can handle them: no one but you can handle your dishes, no one but the developers of the debt can handle the code, losing them is a disaster and the new ones will be demotivated&lt;/li&gt;
&lt;li&gt;One day someone will have to deal with them: imagine you accumulated so many dishes that it is no longer possible to access the kitchen, no buyer will want your apartment (if they see the dishes, meaning they did a technical audit during the company buyout), or will ask for a discount.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here ends the analogy: in IT there are no dishwashers 😉 No machine is there to help you process your technical debt… well, you can still try with AI, I'll let you write the prompt 🙄&lt;/p&gt;

&lt;p&gt;Original post (in French): &lt;a href="https://www.linkedin.com/posts/guillaume-mary-692b578a_il-ny-a-pas-de-diff%C3%A9rence-entre-la-dette-activity-7268171568004968448-JEfB?utm_source=share&amp;amp;utm_medium=member_desktop" rel="noopener noreferrer"&gt;https://www.linkedin.com/posts/guillaume-mary-692b578a_il-ny-a-pas-de-diff%C3%A9rence-entre-la-dette-activity-7268171568004968448-JEfB?utm_source=share&amp;amp;utm_medium=member_desktop&lt;/a&gt;&lt;/p&gt;

</description>
      <category>techdebt</category>
      <category>goodpractice</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Introducing Stalactite ORM</title>
      <dc:creator>Guillaume Mary</dc:creator>
      <pubDate>Mon, 20 May 2024 12:34:24 +0000</pubDate>
      <link>https://dev.to/codefilarete/introducing-stalactite-orm-2n65</link>
      <guid>https://dev.to/codefilarete/introducing-stalactite-orm-2n65</guid>
      <description>&lt;p&gt;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 &lt;strong&gt;method reference&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;As a benefit, you get a better view of the entity graph since the mapping is made through a &lt;strong&gt;fluent API&lt;/strong&gt; 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 &lt;strong&gt;fetches data eagerly&lt;/strong&gt;, we can say that what you see is what you get. Here is a very small example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;MappingEase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entityBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IdentifierPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;afterInsert&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapOneToOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getCapital&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MappingEase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entityBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;City&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;City:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IdentifierPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;afterInsert&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;City:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  First Steps
&lt;/h2&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.codefilarete.stalactite&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;orm-hsqldb-adapter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.0.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;After getting Statactite as a dependency, the next step is to have a JDBC DataSource and pass it to a &lt;code&gt;org.codefilarete.stalactite.engine.PersistenceContext&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hsqldb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;JDBCDataSource&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;org&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hsqldb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;jdbc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;JDBCDataSource&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUrl&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jdbc:hsqldb:mem:test"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"sa"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;PersistenceContext&lt;/span&gt; &lt;span class="n"&gt;persistenceContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PersistenceContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HSQLDBDialect&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then comes the interesting part: the mapping. Supposing you get a &lt;code&gt;Country&lt;/code&gt;, you can quickly set up its mapping through the Fluent API, starting with the &lt;code&gt;org.codefilarete.stalactite.mapping.MappingEase&lt;/code&gt; class as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;EntityPersister&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;countryPersister&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MappingEase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entityBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IdentifierPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;afterInsert&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;persistenceContext&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;afterInsert()&lt;/code&gt; identifier policy means that the country.id column is an auto-increment one. Two other policies exist: the &lt;code&gt;beforeInsert()&lt;/code&gt;for identifier given by a database Sequence (for example), and the &lt;code&gt;alreadyAssigned()&lt;/code&gt; for entities that have a natural identifier given by business rules,&lt;/li&gt;
&lt;li&gt;any non-declared property is considered transient and not managed by Stalactite.
The schema can be generated with the &lt;code&gt;org.codefilarete.stalactite.sql.ddl.DDLDeployer&lt;/code&gt; class as such (it will generate it into the &lt;code&gt;PersistenceContext&lt;/code&gt; dataSource):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;DDLDeployer&lt;/span&gt; &lt;span class="n"&gt;ddlDeployer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DDLDeployer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;persistenceContext&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ddlDeployer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;deployDDL&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you can persist your entities thanks to the &lt;code&gt;EntityPersister&lt;/code&gt; 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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Country&lt;/span&gt; &lt;span class="n"&gt;myCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;myCountry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"myCountry"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="n"&gt;countryPersister&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;insert&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myCountry&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="n"&gt;myCountry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"myCountry with a different name"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="n"&gt;countryPersister&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;update&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myCountry&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="nc"&gt;Country&lt;/span&gt; &lt;span class="n"&gt;loadedCountry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;countryPersister&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myCountry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt; 
&lt;span class="n"&gt;countryPersister&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loadedCountry&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Spring Integration
&lt;/h2&gt;

&lt;p&gt;There was a raw usage of Stalactite, meanwhile, you may be interested in its integration with Spring to benefit from the magic of its &lt;code&gt;@Repository&lt;/code&gt;. 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 &lt;code&gt;@EnableStalactiteRepositories&lt;/code&gt; annotation on your Spring application. Then you'll declare the PersistenceContext and &lt;code&gt;EntityPersister&lt;/code&gt; as &lt;code&gt;@Bean&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Bean&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;PersistenceContext&lt;/span&gt; &lt;span class="nf"&gt;persistenceContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DataSource&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PersistenceContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;
&lt;span class="nd"&gt;@Bean&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;EntityPersister&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;countryPersister&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PersistenceContext&lt;/span&gt; &lt;span class="n"&gt;persistenceContext&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;MappingEase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entityBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; 
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IdentifierPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;afterInsert&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;persistenceContext&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can declare your repository as such, to be injected into your services :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Repository&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;CountryStalactiteRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;StalactiteRepository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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 :&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In these chapters we introduced the Stalactite ORM, more information about the configuration, the mapping, and all the documentation are available on the &lt;a href="https://www.codefilarete.org/"&gt;website&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The project is open-source with the MIT license and shared through &lt;a href="https://github.com/codefilarete/stalactite"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading, any feedback is appreciated!&lt;/p&gt;

</description>
      <category>java</category>
      <category>orm</category>
      <category>jpa</category>
      <category>spring</category>
    </item>
    <item>
      <title>Stalactite ORM 2.0.0 is out ! 🚀</title>
      <dc:creator>Guillaume Mary</dc:creator>
      <pubDate>Sun, 24 Mar 2024 18:31:25 +0000</pubDate>
      <link>https://dev.to/guiommary/stalactite-orm-200-is-out--1fk9</link>
      <guid>https://dev.to/guiommary/stalactite-orm-200-is-out--1fk9</guid>
      <description>&lt;p&gt;Two years after the very first version, &lt;a href="https://www.codefilarete.org/"&gt;Stalactite ORM&lt;/a&gt; is back with a 2.0.0 version released ! 🚀😊&lt;/p&gt;

&lt;p&gt;As a reminder (legit one !), it has a new approach compared to JPA :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mapping is defined by method references instead of Annotations or XML&lt;/li&gt;
&lt;li&gt;its fluent API helps you see the complexity of you graph&lt;/li&gt;
&lt;li&gt;it eagerly fetches your relations to avoid hidden sql queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some of new features :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;composite-keys&lt;/li&gt;
&lt;li&gt;many-to-many relations&lt;/li&gt;
&lt;li&gt;Map mapping&lt;/li&gt;
&lt;li&gt;Spring intégration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To give it a try, see documentation &lt;a href="https://www.codefilarete.org/stalactite-doc/2.0.0/"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>orm</category>
      <category>sql</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Stalactite ORM 1.0.0 is out !</title>
      <dc:creator>Guillaume Mary</dc:creator>
      <pubDate>Sun, 20 Mar 2022 09:54:12 +0000</pubDate>
      <link>https://dev.to/codefilarete/stalactite-orm-100-is-out--16ob</link>
      <guid>https://dev.to/codefilarete/stalactite-orm-100-is-out--16ob</guid>
      <description>&lt;p&gt;After many years of dev, Stalactite ORM is finally released ! It has a brand new approach about persistence :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mapping is defined by method references instead of Annotations or XML&lt;/li&gt;
&lt;li&gt;its fluent API helps you see the complexity of you graph&lt;/li&gt;
&lt;li&gt;it eagerly fetches your relations to avoid hidden sql queries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a short view of what can be achieved with it :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;DataSource&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;// use whatever JDBC DataSource you want&lt;/span&gt;
&lt;span class="nc"&gt;PersistenceContext&lt;/span&gt; &lt;span class="n"&gt;persistenceContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PersistenceContext&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HSQLDBDialect&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="nc"&gt;EntityPersister&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;countryPersister&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MappingEase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entityBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IdentifierPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;afterInsert&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapOneToOne&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Country:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getPresident&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;MappingEase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entityBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Person:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IdentifierPolicy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;afterInsert&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Person:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;persistenceContext&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Country&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Country&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42L&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPresident&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12L&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;countryPersister&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// you can also map an SQL query to build a projection&lt;/span&gt;
&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;allCars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;persistenceContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"select id, model, rgb from Car"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;mapKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;Car:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"model"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Car:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;setModel&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rgb"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Car:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;setColor&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;Color:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Give it a try, see documentation &lt;a href="https://www.codefilarete.org/stalactite-doc/"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>orm</category>
      <category>sql</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
