# Usage of JPA annotations - Configuration

This selection of HOW-TOs will show you how to persist JPA-annotated classes with Castor JDO, and will outline the required steps for each of the following cases:

- Singular (stand-alone) entities

- 1:1 relations

- 1:M relations

- M:N relations

## HOW-TO persist a single class (@Entity, @Table, @Id)

The goal is to take an existing JPA-annotated class Single and persist it with Castor JDO. Let's first have a look at the domain class itself, first without JPA annotattions.

    public class Single {
       private int id;
       private String name;

       public int getId() { ... }

       public void setId(int id ) { ... }

       public String getName() { ... }

       public void setName(String name) { ... }
    }

Here's the same class again, this time with JPA annotations.

    @Entity
    @Table(name="mySingleTable")
    public class Single {
       private int id;
       private String name;

       @Id
       @Column(name="id")
       public int getId() { ... }

       public void setId(int id) { ... }

       public String getName() { ... }

       public void setName(String name) { ... }
    }

As shown, the class Single is mapped against the table `mySingleTable`, and its fields `id` and `name` are mapped to the columns `id` and `name`, where the column name for the `id` property is supplied explicitly and where the column name for the `name` property is derived from the property itself.

Next point is to create an DAO interface and its implementation where we will be using CastorDaoSupport from Castor's support for Spring ORM to implement the required methods.

    public interface SingleDao {

        void save(Single single);

        Single get(int id);

        void delete(Single single);

    }

    public class SingleCastorDao extends CastorDaoSupport implements SingleDao {

        public void delete(Single single) {
            this.getCastorTemplate().remove(single);
        }

        public Single get(int id) {
            return (Single) this.getCastorTemplate().load(Single.class, Integer.valueOf(id));
        }

        public void save(Single single) {
            this.getCastorTemplate().create(single);
        }
    }

There's one small final code change needed: For Castor to be able to work with JPA-annotated classes, you have to configure an instance of JDOClassDescriptorResolver and pass it to your JDOManager, else Castor won't be able to see those class files. Simply add the individual classes one by one or the package(s) as shown below:

    JDOClassDescriptorResolver resolver = new JDOClassDescriptorResolverImpl();
    resolver.addClass(org.castor.jpa.Single.class);
    // or alternatively you can add the package:
    resolver.addPackage("org.castor.jpa");

    InputSource jdoConfiguration = ...;
    JDOManager.loadConfiguration(jdoConfiguration, null, null, resolver);

    JDOManager jdoManager = JDOManager.createInstance("jpa-extensions");
    ...

## HOW-TO persist a 1:1 relation (@OneToOne)

The goal is to take the existing JPA-annotated classes OneToOne_A and OneToOne_B and persist them with Castor JDO. Let's first have a look at the domain classes themselves, this time with JPA annotations already in place.

    @Entity
    public class OneToOne_A {

       private int id;
       private String title;

       @Id
       @Column(name = "id")
       public int getId() { ... }

       public void setId(int id) { ... }

       @Column(name = "name")
       public String getTitle() { ... }

       public void setTitle(String title) { ... }
    }

    @Entity
    @Table(name="OneToOne_B")
    public class B {

       private int id;
       private String name;
       private OneToOne_A objA;

       @Id
       @Column(name = "id")
       public int getId() { ... }

       public void setId(int id) { ... }

       @Column(name = "name")
       public String getName() { ... }

       public void setName(String name) { ... }

       @OneToOne(optional=false)
       public OneToOne_A getOneToOne_A() { ... }

       public void setOneToOne_a(OneToOne_A objA) { ... }
    }

As shown, the class OneToOne_A is mapped against the table `OneToOne_A` (implicit mapping), and the B against the table `OneToOne-B` (explicit mapping). Please note the `@OneToOne` annotation that specifies the 1:1 relation from class B to class OneToOne_A.

As with the example shown further above, do not forget to register all classes involved with the JDOClassDescriptorResolver as shown below:

JDOClassDescriptorResolver fragment:

    resolver.addClass(org.castor.jpa.OneToOne_A.class);
    resolver.addClass(org.castor.jpa.B.class);

or with the addPackage method:

    resolver.addPackage("org.castor.jpa");

## Persist one to many relation (@OnetoMany)

First we have to annotate our java classes.

        @Entity
        @Table(name="OneToMany_actor")
        public class Actor {

            private int svnr;
            private String lastname;
            private String firstname;

            @Id
            public int getSvnr() { ... }

    	public void setSvnr(int svnr) { ... }

            @Column(name="surname")
            public String getLastname() { ... }
            public void setLastname(String lastname) { ... }

            @Column(name="firstname")
            public String getFirstname() { ... }
            public void setFirstname(String firstname) { ... }
        }

        @Entity
        @Table(name="OneToMany_broadcast")
        public class Broadcast {

            private int id;
            private String name;
            private Collection<Actor> actors;

            @Id
            public int getId() { ... }

            public void setId(int id) { ... }

            public String getName() { ... }

            public void setName(String name) { ... }

            @OneToMany(targetEntity=Actor.class, mappedBy="actor_id")
            public Collection<Actor>  getActors() { ... }

            public void setActors(Collection<Actor> actors) { ... }
        }

What you see is that with the small modification you can persist one to many relations easily.

Last don't forget to change your JDOClassDescriptorResolver accordingly.

## HOW-TO create and use a named query (@NamedQuery)

The `@NamedQuery` annotation is used to specify a named query in castor's own query language (OQL) and it is expressed in metadata. The annotation takes the `name` and an OQL `query` as parameters.

To define a named query, we first need a persistence entity where we can attach the `@NamedQuery` annotation.

    package your.package;

    @Entity
    @NamedQuery(name = "findPersonByName",
                query = "SELECT p FROM your.package.Person p WHERE p.name = $1")
    public class Person {

        private long id;
        private String name;

    	@Id
    	public long getId() {...}

    	public void setId(final long id) {...}

    	public String getName() {...}

    	public void setName(final String name) {...}
    }

As you can see, we defined a query using the name `findPersonByName`. The query itself uses `$1` as a placeholder in its `WHERE`-clause, which must be bound when executing the query.

The following code sample illustrates how to execute the named query defined above:

    Database db = jdoManager.getDatabase();

    db.begin();
    final OQLQuery query = db.getNamedQuery("findPersonByName");
    query.bind("Max Mustermann");
    final QueryResults queryResults = query.execute();
    final Person queriedPerson = (Person) queryResults.next();
    queryResults.close();
    db.commit();

Let's have a closer look on some of the lines from this example.

... creates an OQL query using the above defined named query.

.. binds the placeholder `$1` to a value.

... executes the query and handle the results.

## HOW-TO create and use multiple named queries (@NamedQueries)

The `@NamedQueries` annotation is used to specifiy multiple named queries.

    package your.package;

    @Entity
    @NamedQueries({
        @NamedQuery(name = "findPersonByName",
                    query = "SELECT p FROM your.package.Person p WHERE p.name = $1"),
        @NamedQuery(name = "findPersonById",
                    query = "SELECT p FROM you.package.Person p WHERE p.id = $1")
    })
    public class Person {

        private long id;
        private String name;

        @Id
        public long getId() {...}

        public void setId(final long id) {...}

        public String getName() {...}

        public void setName(final String name) {...}
    }

In the obove example we defined two named queries, namly `findPersonByName` and `findPersonById`. The usage of each query is identical to the usasage of a single named query.

    Database db = jdoManager.getDatabase();

    db.begin();
    final OQLQuery query = db.getNamedQuery("findPersonById");
    query.bind(1000L);
    final QueryResults queryResults = query.execute();
    final Person queriedPerson = (Person) queryResults.next();
    queryResults.close();
    db.commit();

## HOW-TO create and use a named native query (@NamedNativeQuery)

A named native query is a named query using native SQL syntax instead of castor's own query language. The handling of the annotation is similar to named queries.

First we need a entity to attach a query.

    @Entity
    @Table(name = personTable)
    @NamedNativeQuery(name = "selectAllPersons",
                      query = "SELECT * FROM personTable")
    public class Person {

        private long id;
        private String name;

    	@Id
    	public long getId() {...}

    	public void setId(final long id) {...}

    	public String getName() {...}

    	public void setName(final String name) {...}
    }

Although the `query` itself is written in native SQL syntax, we - again - use a OQLQuery object to execute the query.

    Database db = jdoManager.getDatabase();

    db.begin();
    final OQLQuery query = db.getNamedQuery("selectAllPersons");
    final QueryResults queryResults = query.execute();
    ... //process the results
    queryResults.close();
    db.commit();

## HOW-TO create and use multiple named native queries (@NamedNativeQueries)

The `@NamedNativeQueries` annotation is used to specifiy multiple named native SQL queries.

    package your.package;

    @Entity
    @Table(name = personTable)
    @NamedNativeQueries({
        @NamedNativeQuery(name = "selectAllPersons",
                          query = "SELECT * FROM personTable"),
        @NamedNativeQuery(name = "findMustermann",
                          query = "SELECT * FROM personTable WHERE name='Max Mustermann' and id=1000")
    })
    public class Person {

        private long id;
        private String name;

        @Id
        public long getId() {...}

        public void setId(final long id) {...}

        public String getName() {...}

        public void setName(final String name) {...}
    }

As we have already seen, the usage of the two above defined queries is equivalent to the usage of a single named native query.

    Database db = jdoManager.getDatabase();

    db.begin();
    final OQLQuery query = db.getNamedQuery("findMustermann");
    final QueryResults queryResults = query.execute();
    final Person maxMustermann = (Person) queryResults.next();
    queryResults.close();
    db.commit();

## HOW-TO use persistence callbacks

The following annotations can be used for handling persistence callbacks via JPA:

- PostLoad
- PrePersist
- PostPersist
- PreUpdate
- PostUpdate
- PreRemove
- PostRemove

Additionally, there are the following listener-related annotations:

- EntityListeners
- ExcludeDefaultListeners
- ExcludeSuperclassListeners

So, here's a basic usage example:

    @Entity
    public class Person {

        private final Log log = LogFactory.getLog(this.getClass());

        private long id;
        private String name;

        @Id
        public long getId() {
            return id;
        }

        public void setId(final long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        @PostLoad
        protected void testPostLoadCallbackHooking() {
            log.debug(String.format("Hello from `PostLoad`. My name is %s.",
                    this.name));
        }

        @PrePersist
        protected void validateCreation() {
            if (this.name.equals("Max Mustermann")) {
                throw new PersistenceException(String.format(
                        "Person mustn't be called %s.", this.name));
            }
        }

        @PostPersist
        protected void validatePersistence() {
            if (this.name.equals("Manfred Mustermann")) {
                throw new PersistenceException(String.format(
                        "Person shouldn't be called %s either.", this.name));
            }
        }

        @PreRemove
        protected void validateRemoval() {
            if (this.name.equals("Max Musterfrau")) {
                throw new PersistenceException(this.name + " mustn't be removed.");
            }
        }

        @PostRemove
        protected void validateDeletion() {
            if (this.name.equals("Manfred Musterfrau")) {
                throw new PersistenceException(this.name
                        + " shouldn't be removed either.");
            }
        }

        @PreUpdate
        protected void validateModification() {
            if (this.name.equals("Max Musterfrau")) {
                throw new PersistenceException(String.format(
                        "Person mustn't be renamed to %s.", this.name));
            }
        }

        @PostUpdate
        protected void validateUpdating() {
            if (this.name.equals("Hans Wurst")) {
                throw new PersistenceException(String.format(
                        "Person shouldn't be renamed to %s either.", this.name));
            }
        }

    }

As one can see from this example, such callbacks can e.g. be used for handling validation based on CRUD (create, retrieve, update, delete) operation events.

Furthermore, there are possibilites to define listeners which allow for decoupling callback handling from entities.

Here's an example for that:

    @Entity
    @EntityListeners(DogListener.class)
    public class Dog extends Animal {

        private long id;

        @Id
        public long getId() {
            return id;
        }

        public void setId(final long id) {
            this.id = id;
        }

    }

    // Corresponding listener.
    public class DogListener {

        @PostPersist
        protected void postPersistDogListener() {
            // Do something.
        }

    }

Apart from that, `ExcludeDefaultListeners` and `ExcludeSuperclassListeners` enable specifying exclusion of listeners within an inheritance chain of entities.

## HOW-TO use @Enumerated

`Enumerated` can be used to persist `Enum` types.

Here's an example:

    @Entity
    public class EnumEntity {

        private long id;
        private StringEnum stringEnum;
        private OrdinalEnum ordinalEnum;

        @Id
        public long getId() {
            return id;
        }

        public void setId(final long id) {
            this.id = id;
        }

        @Enumerated(STRING)
        public StringEnum getStringEnum() {
            return stringEnum;
        }

        public void setStringEnum(final StringEnum stringEnum) {
            this.stringEnum = stringEnum;
        }

        public OrdinalEnum getOrdinalEnum() {
            return ordinalEnum;
        }

        public void setOrdinalEnum(final OrdinalEnum ordinalEnum) {
            this.ordinalEnum = ordinalEnum;
        }

    }

So, by default enums are serialized to their corresponding ordinal value representations for persistence. In this case, it's also sufficient to skip explicitly defining so via `Enumerated`. If serialization to respective string name representations is preferred annotating accordingly is required.

## HOW-TO use @Temporal

This annotation can be used to specify properties mapped to temporal data structures.

Example:

    @Entity
    public class Person {

        private long id;
        private Date birthDate;
        private Date anotherDate;
        private Date yetAnotherDate;

        @Id
        public long getId() {
            return id;
        }

        public void setId(final long id) {
            this.id = id;
        }

        @Temporal(TIMESTAMP)
        public Date getBirthDate() {
            return birthDate;
        }

        public void setBirthDate(final Date birthDate) {
            this.birthDate = birthDate;
        }

        @Temporal(TIME)
        public Date getAnotherDate() {
            return anotherDate;
        }

        public void setAnotherDate(final Date anotherDate) {
            this.anotherDate = anotherDate;
        }

        @Temporal(DATE)
        public Date getYetAnotherDate() {
            return yetAnotherDate;
        }

        public void setYetAnotherDate(final Date yetAnotherDate) {
            this.yetAnotherDate = yetAnotherDate;
        }

    }

So, it's possible to say which underlying DB-based field data structure to use (datetime, date or time).

## HOW-TO use @Lob

Here's an example for that:

    @Entity
    public class LobEntity {

        private long id;
        private String clob;
        private byte[] blob;

        @Id
        public long getId() {
            return id;
        }

        public void setId(final long id) {
            this.id = id;
        }

        @Lob
        public String getClob() {
            return clob;
        }

        public void setClob(final String clob) {
            this.clob = clob;
        }

        @Lob
        public byte[] getBlob() {
            return blob;
        }

        public void setBlob(final byte[] blob) {
            this.blob = blob;
        }

    }

Consequently, default behavior here is to serialize to `CLOB` for character-based data and to `BLOB` for data based on byte arrays (i.e., files).