Strategies for abstracting db id from domain class
<p>I am writing a simple CRUD application in Java and Spring4 with spring-data, and I want to see if I can keep the domain as pure/clean as possible, and I'm after some ideas/thoughts as to how I can go about achieving this.<br>
I've structured the project with a parent pom and some child modules as follows:</p>

<pre><code>parent pom
    |- domain
    |
    |- persistence
    |   |- api
    |   |- impl
    |
    |- service
    |   |- api
    |   |- impl
    |
    |- rest
</code></pre>

<p>In the persistence api module I have interfaces with methods for persisting/retrieving my domain classes. eg:</p>

<pre><code>public interface GiftPersistence() {

    Gift saveOrUpdateGift(Gift gift);
    /* other methods ... */
}
</code></pre>

<p>Importantly, these methods are <strong>not</strong> repository methods. The methods in this module are those that are called by the service module implementations.</p>

<p>The persistence impl module has an implementation of the interface that is specific to the database that I'm using (it's mongo today, but could be oracle or ms-sql, or anything else). This is where I have my repository interface that is specific to the database vendor.</p>

<p>In the domain module I have my domain classes, but I don't want to model in anything that is database centric. eg:</p>

<pre><code>public final class Gift {

    private String description;

    private boolean claimed;

    private String claimedBy;

    /* getters &amp; setters etc ... */
}
</code></pre>

<p>The reasons I don't want to model database specific things are:</p>

<ul>
<li>Persistence is not a concern of the domain</li>
<li>Different database vendors might use different id strategies/datatypes, and I don't want to couple my domain code to any database vendor</li>
<li>I might want to import the domain module into another project's pom, and that project might not do anything with a database</li>
</ul>

<p>I've been involved in a project in the past that did something similar (to be honest, that's where I've got the idea from!), but I don't have access to that project any more so can't use it to crib ideas.<br>
Having said that I vaguely remember it did something with jackson mixins (though that might have been a similar idea/concept, but closer to the web concern than the db concern).<br>
The other approach I've thought about is using aspects, but not really sure how/where I'd go about that.</p>

<p>So, any ideas or thoughts as to how I might achieve the goal of keeping my domain clean of database concerns would be very much appreciated.</p>

<p><strong>Edited with new idea I just found</strong><br>
This is an interesting idea - <a href="https://github.com/CK35/example-ddd-with-spring-data-jpa" rel="nofollow">https://github.com/CK35/example-ddd-with-spring-data-jpa</a><br>
The idea is that the domain module models the domain classes as interfaces, and the concrete implementations are (in my case) in the persistence-impl module. This way they can be annotated with domain concerns, including additional properties such as id.<br>
This feels like a nice option as it means the domain is clean (albeit not a concrete implementation), and we can have different implementations of the persistence-api module, where the implementations of the domain classes have generic jpa annotations, or mongo annotations, or oracle ... </p>

<p>Any other ideas?</p>