# 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, new Integer(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();