= Mapping Guide

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
:page-aliases: guides:ugvw:ugvw.adoc


There are plenty of resources for learning JPA annotations.
Take a look at:

* link:https://spring.io/guides/gs/accessing-data-jpa/[Spring Boot: Accessing Data with JPA]

* link:https://github.com/spring-projects/spring-data-book/tree/master/jpa/src/main/java/com/oreilly/springdata/jpa[Spring Daata Book - sample code showing several entities]

* link:https://www.vogella.com/tutorials/JavaPersistenceAPI/article.html[Vogella JPA tutorial]

* link:https://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html[JBoss reference guide]
+
Although written for Hibernate, the JPA material should work fine.

* link:https://www.baeldung.com/tag/jpa/[JPA Baeldung tags]

== Custom Value Types

The framework provides a number of custom value types.
Some of these are wrappers around a single value (eg `AsciiDoc` or `Password`) while others map onto multiple values (eg `Blob`).

This section shows how to map each (and can be adapted for your own custom types or `@Embedded` values).


=== Mapping AsciiDoc

The xref:refguide:valuetypes:index/asciidoc/applib/value/AsciiDoc.adoc[] value type is used for documentation written using the link:https://asciidoctor.org/[AsciiDoc] syntax:

* In the domain entity, map `AsciiDoc` type using `@Lob`:
+
[source,java]
.MyEntity.java
----
public class MyEntity ... {

    @Column(nullable = false) @Lob @Basic(fetch=FetchType.LAZY)
    @Property
    @Getter @Setter
    private AsciiDoc documentation;

}
----

* in the webapp module, register the JPA specific converter by:

** adding a dependency to this module:
+
[source,xml]
.pom.xml
----
<dependency>
    <groupId>org.apache.isis.valuetypes</groupId>
    <artifactId>isis-valuetypes-asciidoc-persistence-jpa</artifactId>
</dependency>
----

** and adding reference the corresponding module in the `AppManifest`:
+
[source,java]
.AppManifest.java
----
@Configuration
@Import({
        ...
        IsisModuleValAsciidocPersistenceJpa.java
        ...
})
public class AppManifest {
}
----

=== Mapping Markdown

The xref:refguide:valuetypes:index/markdown/applib/value/Markdown.adoc[] value type is used for documentation written using markdown:

* In the domain entity, map `Markdown` type using `@Lob`:
+
[source,java]
.MyEntity.java
----
public class MyEntity ... {

    @Column(nullable = false) @Lob @Basic(fetch=FetchType.LAZY)
    @Property
    @Getter @Setter
    private Markdown documentation;

}
----

* in the webapp module, register the JPA specific converter by:

** adding a dependency to this module:
+
[source,xml]
.pom.xml
----
<dependency>
    <groupId>org.apache.isis.valuetypes</groupId>
    <artifactId>isis-valuetypes-markdown-persistence-jpa</artifactId>
</dependency>
----

** and adding reference the corresponding module in the `AppManifest`:
+
[source,java]
.AppManifest.java
----
@Configuration
@Import({
        ...
        IsisModuleValMarkdownPersistenceJpa.java
        ...
})
public class AppManifest {
}
----


=== Mapping Blobs and Clobs

While the JPA standard does provide a standardised mechanism to marshall single valued types, but does not (currently) provide a standardised mechanism to marshall multiple valued types.

There are two alternatives:

* use EclipseLink-specific extensions, specifically its link:https://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_transformation.htm[@Transformation] annotation and the related link:https://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_writetransformer.htm#BGBGGAEA[@WriteTransformer] and link:https://www.eclipse.org/eclipselink/documentation/2.5/jpa/extensions/a_readtransformer.htm#CHDGHHBA[@ReadTransformer].

* manually map the class to an link:https://www.eclipse.org/eclipselink/documentation/3.0/concepts/entities005.htm#BABGBFDG[@Embeddable] class.

We think the second approach is less boilerplate overall, and is easier to understand what is going on.
The framework provides an `@Embeddable` classes for each of `Blob` and `Clob`, explained in the sections below.

==== Blobs

To map a xref:refguide:applib:index/value/Blob.adoc[Blob], use the xref:refguide:persistence:index/jpa/applib/types/BlobJpaEmbeddable.adoc[BlobJpaEmbeddable] class:

[source,java]
.MyEntity.java
----
public class MyEntity ... {

    @Embedded
    private BlobJpaEmbeddable pdf;              // <.>

    @Property()
    @PropertyLayout()
    public Blob getPdf() {                      // <.>
        return BlobJpaEmbeddable.toBlob(pdf);
    }
    public void setPdf(final Blob pdf) {
        this.pdf = BlobJpaEmbeddable.fromBlob(pdf);
    }
}
----

<.> the field as it is persisted by the ORM
<.> the property as it is understood by Apache Isis.


TIP: if you have multiple instancs of an `@Embedded` type, the `@javax.persistence.AttributeOverrides` and `@javax.persistence.AttributeOverride` provide a standardised way of fine-tuning the column definitions.

==== Clobs

To map a xref:refguide:applib:index/value/Clob.adoc[Clob], use the xref:refguide:persistence:index/jpa/applib/types/ClobJpaEmbeddable.adoc[ClobJpaEmbeddable] class:

[source]
.MyEntity.java
----
public class MyEntity ... {

    @Embedded
    private ClobJpaEmbeddable xml;              // <.>

    @Property()
    @PropertyLayout()
    public Clob getXml() {                      // <.>
        return ClobJpaEmbeddable.toClob(xml);
    }
    public void setXml(final Clob xml) {
        this.xml = ClobJpaEmbeddable.fromClob(xml);
    }
}
----

<.> the field as it is persisted by the ORM
<.> the property as it is understood by Apache Isis.


TIP: if you have multiple instances of an `@Embedded` type, the `@javax.persistence.AttributeOverrides` and `@javax.persistence.AttributeOverride` provide a standardised way of fine-tuning the column definitions.
