simple Step by Step JPA-JAXP-REST

Da ich mir ja langsam mal Gedanken machen sollte, wie ich meine Arbeit strukturiere. Habe ich mal angefangen, beispielhaft, die Schritte zu sammeln, welche notwendig sind, um eine DB Table mit Hilfe der Java Möglichkeiten REST fähig zu machen.
Ich gedenke dies in 3 Teile zu tun:

  1. JPA Entity: Wie wird aus einer Datenbank Tabelle ein Java Objekt
  2. JAXP: Wie bekomme ich von meiner JPA Entity möglichst einfach eine Repräsentation in XML (JSON geht auch, aber erstmal reicht mir XML).
  3. JSR311/Jersey: Wie gelingt, es die Ressourcen an bestimmte URIs zu binden?

Hier dann als mal Teil 1:

Als allererstes möchte ich die folgende Datenbank Tabelle als ein einfaches POJO (Plain Old Java Object) abbilden und die Annotations machen, welche notwendig sind, damit JPA auch weiß, wie es mit der Klasse umzugehen hat.
Folgende Tabelle:

TABLE Users
===================================================
[ user_id | email | forename | surname | password ]
===================================================

Die nachfolgende Klasse ist dann das passende POJO dazu:

/*
ne ganze menge imports:
*/
import de.hausswolff.cotodo.tools.Tools;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/*
Leider scheint der JPA Layer verschiedene Schlüsselwörter für sicher selbst in Anspruch zu nehmen. 
"User" gehört scheinbar auch dazu.
Ich musste also diese Klasse hier dann Users nennen und blieb bei den Entitäten nun bei dem Plural.
*/
@Entity
@Table(name = "Users")
public class Users implements Serializable {
    @Id
    @Column(name = "user_id", nullable = false)
    private Integer userId;

    @Column(name = "forename", nullable = false)
    private String forename;

    @Column(name = "surname", nullable = false)
    private String surname;

    @Column(name = "email", nullable = false)
    private String email;

    @Column(name = "password", nullable = false)
    private String password;

    /*
    Hier kommt dann noch eine Reihe von den Beziehungen der Entitäten untereinander. 
    Das lasse ich hier jetzt auch mal weg, weil es zum Thema keine Rolle spielt. 
    Als Beispiel mal eine Beziehung zu der Table Tasks über folgende Tabelle:
    TABLE UsersTasks
    ===============================
    [ task_id | user_id | send_to ]
    ===============================
    Hierbei ist "task_id" die ID des Tasks ;-). user_id ist die ID des Users, welcher den Tasks erstellt hat. 
    send_to enthält die ID des Users, an den der Task als Auftrag geschickt worden ist. 
    Da es n Empfänger seien sollen, muss das ganze natürlich in eine externe Tabelle ausgelagert werden.
    */

    @ManyToMany
    @JoinTable(name="UsersTasks",
    joinColumns=@JoinColumn(name="user_id"),
    inverseJoinColumns=@JoinColumn(name="task_id"))
    private Collection SendTaskCollection;

    @ManyToMany
    @JoinTable(name="UsersTasks",
    joinColumns=@JoinColumn(name="send_to"),
    inverseJoinColumns=@JoinColumn(name="task_id"))
    private Collection ReceivedTaskCollection;

    /*
    als (quasi virtuelle) Attribute erhält jede Users Klasse nun zwei Collections, 
    welche halt nicht direkt in der Users Tabelle gespeichert werden, 
    aber durch die Relationen in der UsersTasks Tabelle abgelegt sind.
    */
    public Users() {

    }
    public Users(Integer userId) {
        this.userId = userId;
    }

    public Users(Integer userId, String forename, String surname, String email, String password) {
        this.userId = userId;
        this.forename = forename;
        this.surname = surname;
        this.email = email;
        this.password = Tools.md5(password);
    }
    /*
    Es folgt nun die übliche Anzahl an gettern/settern. Hierbei habe ich mich entschlossen, 
    nicht stumpfsinnig alle Attribute per set zu öffnen, sondern wirklich nur jene, bei denen es notwendig ist. 
    Die beiden Listen aus den obigen relationen sollten nur lesbar sein. Der Empfänger/Ersteller werden im Task direkt angegeben.
    Als Beispiel hier mal setter/getter für das Passwort:
    */

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = Tools.md5(password);
    }

...

}

Ich habe vieles aus der Klasse weg gelassen, was nicht unbedingt für die Funktion von JPA notwendig ist, aber durchaus der besseren Lesbarkeit dient. Wichtig ist, dass es einen Standard-Konstruktor gibt.
Weiter geht es mit JAXP. Also der Repräsentation von obiger Klasse in XML.

Leave a Reply