Hibernate 3 mit JPA

From no name for this wiki
Jump to: navigation, search

Hello World

JPA Java Persistence API Sample mit Hibernate und Derby DB. Ohne Applicationserver; standalone Applikation. Folgende JARs müsssen im Classpath sein:

  • derby.jar
  • antlr-2.7.6.jar
  • asm.jar asm-attrs.jar
  • c3p0-0.9.1.jar
  • cglib-2.1.3.jar
  • commons-collections-2.1.1.jar
  • commons-logging-1.0.4.jar
  • dom4j-1.6.1.jar
  • ejb3-persistence.jar
  • hibernate3.jar
  • hibernate-annotations.jar
  • hibernate-commons-annotations.jar
  • hibernate-entitymanager.jar
  • javassist.jar
  • jboss-common.jar
  • jta.jar

derby.jar wird mit Sun's JDK 1.6 mitgeliefert (jdk_home/db). Beim Herunterladen von Hibernate darauf achten, dass kompatible Versionen heruntergeladen werden. Hibernate hat eine handvoll von Modulen. Im Sample wird Core, Annotations und Entitymanger benötigt. Hier die Files des Sample:

Die Datei persistence.xml ist im Verzeichnis META-INF, die Datei hibernate.cfg.xml im Rootverzeichnis der Classfiles.

Many to Many

Team.java

package hibernatesample;
 
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
 
@Entity()
@Table(name = "team")
public class Team implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
 
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="TEAM2MEMBER",
        joinColumns=
            @JoinColumn(name="teamid", referencedColumnName="id"),
        inverseJoinColumns=
            @JoinColumn(name="memberid", referencedColumnName="id")
    )
    private List<Member> members = new ArrayList<Member>();
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the members
     */
    public List<Member> getMembers() {
        return members;
    }
 
    /**
     * @param members the members to set
     */
    public void setMembers(List<Member> members) {
        this.members = members;
    }
 
}

Member.java

package hibernatesample;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
 
@Entity()
@Table(name = "mymember")
public class Member implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="TEAM2MEMBER",
        joinColumns=
            @JoinColumn(name="memberid", referencedColumnName="id"),
        inverseJoinColumns=
            @JoinColumn(name="teamid", referencedColumnName="id")
    )
    private List<Team> team = new ArrayList<Team>();
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the team
     */
    public List<Team> getTeam() {
        return team;
    }
 
    /**
     * @param team the team to set
     */
    public void setTeam(List<Team> team) {
        this.team = team;
    }
 
}

Main.java

package hibernatesample;
 
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class Main {
 
    private static final Log log = LogFactory.getLog(Main.class);
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("HibernateSamplePU");
        EntityManager em = emf.createEntityManager();
        EntityTransaction transaction = em.getTransaction();
 
 
        transaction.begin();
        Team t = new Team();
        Member m = new Member();
        t.getMembers().add(m);
        em.persist(t);
 
        transaction.commit();
 
 
        em.close();
    }
 
}

One to One

Strategie mit Foreign-Key

Husband

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@Entity()
public class Husband implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @OneToOne (mappedBy="husband")
    private Wife wife;
 
    @Column(name="name")
    private String name;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the wife
     */
    public Wife getWife() {
        return wife;
    }
 
    /**
     * @param wife the wife to set
     */
    public void setWife(Wife wife) {
        this.wife = wife;
    }
 
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
 
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
 
}

Wife

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@Entity
public class Wife implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
 
    @OneToOne
    @JoinColumn( name="MYHUSBAND_ID", unique=false, nullable=true)
    private Husband husband;
 
    @Column(name="name")
    private String name;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the husband
     */
    public Husband getHusband() {
        return husband;
    }
 
    /**
     * @param husband the husband to set
     */
    public void setHusband(Husband husband) {
        this.husband = husband;
    }
 
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
 
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
 
}

Der Foreign Key befindet sich in der Tabelle Wife.

Strategie mit Primärschlüssel

Wife:

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@Entity
public class Wife implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
 
    @OneToOne
    @PrimaryKeyJoinColumn
    private Husband husband;
 
    @Column(name="name")
    private String name;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the husband
     */
    public Husband getHusband() {
        return husband;
    }
 
    /**
     * @param husband the husband to set
     */
    public void setHusband(Husband husband) {
        this.husband = husband;
    }
 
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
 
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
 
}


Husband:

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@Entity()
public class Husband implements Serializable {
 
    @Id
    @Column(name = "id")
    private Long id;
 
 
    @Column(name="name")
    private String name;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
 
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
 
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
 
}

persistence.xml

Hier ein persistence.xml Beispiel:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="HibernateSamplePU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <class>hibernatesample.Message</class>
    <properties>
      <property name="hibernate.connection.username" value="app"/>
      <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="hibernate.connection.password" value="app"/>
      <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/sample"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
      <property name="hibernate.show_sql" value="true" />
    </properties>
  </persistence-unit>
</persistence>

Secondary Table

Eine Entität auf zwei Tabellen verteilt, HugeObject:

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@Entity
@Table(name="PRIMTABLE")
@SecondaryTable(name="SECTABLE", pkJoinColumns=@PrimaryKeyJoinColumn(name="PARENT_ID"))
public class HugeObject implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Basic
    @Column(name="name1")
    private String name1;
 
    @Basic
    @Column(name="name2", table="SECTABLE")
    private String name2;
 
    @Basic
    @Column(name="name3", table="SECTABLE")
    private String name3;
 
}

Named queries

In der Entität:

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "message")
@NamedQueries({
    @NamedQuery(name="query1Message",
        query="SELECT x FROM Message x WHERE x.id > ?1"),
    @NamedQuery(name="magsByTitle",
        query="SELECT x FROM Message x WHERE x.messageText = :messageParam")
})
public class Message implements Serializable {
 
    @Id
    @Column(name = "id")
    private Long id;
 
    @Column(name = "messagetext")
    private String messageText;
 
 
    /** Creates a new instance of Message */
    public Message() {
    }
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getMessageText() {
        return messageText;
    }
 
    public void setMessageText(String messageText) {
        this.messageText = messageText;
    }
 
}

Im Business Code:

 
        Query query2 =  em.createNamedQuery("magsByTitle"); //em ist ein EntityManager
        query2.setParameter("messageParam", "Hugo");
        List<Message> results = query2.getResultList ();
 
        for(Message messy : results){
            log.info(messy.getMessageText());
        }
 
        em.close();

Relationships und Identity

Question.java:

package hibernatesample;
 
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "question")
public class Question implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "questiontext")
    private String questionText;
 
 
    @OneToMany(mappedBy="question", cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    private List<QuestionOption> options = new ArrayList<QuestionOption>();
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the questionText
     */
    public String getQuestionText() {
        return questionText;
    }
 
    /**
     * @param questionText the questionText to set
     */
    public void setQuestionText(String questionText) {
        this.questionText = questionText;
    }
 
    /**
     * @return the options
     */
    public List<QuestionOption> getOptions() {
        return options;
    }
 
    /**
     * @param options the options to set
     */
    public void setOptions(List<QuestionOption> options) {
        this.options = options;
    }
}

Klasse QuestionOption.java

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
 
@Entity()
@Table(name = "questionoption")
public class QuestionOption implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "optionText")
    private String optionText;
 
    @Column(name = "correct")
    private boolean correct;
 
    @ManyToOne(optional=false, fetch = FetchType.EAGER)
    @JoinColumn(name="questionid", nullable=false)
    private Question question;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the optionText
     */
    public String getOptionText() {
        return optionText;
    }
 
    /**
     * @param optionText the optionText to set
     */
    public void setOptionText(String optionText) {
        this.optionText = optionText;
    }
 
    /**
     * @return the correct
     */
    public boolean isCorrect() {
        return correct;
    }
 
    /**
     * @param correct the correct to set
     */
    public void setCorrect(boolean correct) {
        this.correct = correct;
    }
 
    /**
     * @return the question
     */
    public Question getQuestion() {
        return question;
    }
 
    /**
     * @param question the question to set
     */
    public void setQuestion(Question question) {
        this.question = question;
    }
 
 
}

Embedded Klassen

Embedded Objekte werden in die Tabelle der Entität integriert.

Klasse, welche ein andere Klasse "embedded".

package hibernatesample;
 
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity()
@Table(name = "myembedder")
public class MyEmbedder {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Embedded
    private MyEmbeddedClass myEmeddedClass;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the myEmeddedClass
     */
    public MyEmbeddedClass getMyEmeddedClass() {
        return myEmeddedClass;
    }
 
    /**
     * @param myEmeddedClass the myEmeddedClass to set
     */
    public void setMyEmeddedClass(MyEmbeddedClass myEmeddedClass) {
        this.myEmeddedClass = myEmeddedClass;
    }
}

Embedded Klasse

package hibernatesample;
 
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
 
 
@Embeddable
public class MyEmbeddedClass {
 
    @Column(length = 50,name = "erstelltdurch")
    private String createdBy;
 
 
    @Temporal(value = TemporalType.TIMESTAMP)
    @Column(name = "erstelltam")
    private Date dateCreated;
 
    /**
     * @return the createdBy
     */
    public String getCreatedBy() {
        return createdBy;
    }
 
    /**
     * @param createdBy the createdBy to set
     */
    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }
 
    /**
     * @return the dateCreated
     */
    public Date getDateCreated() {
        return dateCreated;
    }
 
    /**
     * @param dateCreated the dateCreated to set
     */
    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }
 
}

IdClass

Klasse mit einem composite Key;

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@Entity
@IdClass(WineBottlePK.class)
public class WineBottle implements Serializable {
 
    @Id
    private Integer wineyear;
 
    @Id
    private Integer num;
 
    @Basic
    private String label;
 
 
 
    /**
     * @return the num
     */
    public Integer getNum() {
        return num;
    }
 
    /**
     * @param num the num to set
     */
    public void setNum(Integer num) {
        this.num = num;
    }
 
    /**
     * @return the label
     */
    public String getLabel() {
        return label;
    }
 
    /**
     * @param label the label to set
     */
    public void setLabel(String label) {
        this.label = label;
    }
 
    /**
     * @return the wineyear
     */
    public Integer getWineyear() {
        return wineyear;
    }
 
    /**
     * @param wineyear the wineyear to set
     */
    public void setWineyear(Integer wineyear) {
        this.wineyear = wineyear;
    }
 
}

Primary-Key Klasse als embeddable

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@Embeddable
public class WineBottlePK implements Serializable {
 
 
    @Basic
    private Integer wineyear;
 
    @Basic
    private Integer num;
 
 
    /**
     * @return the num
     */
    public Integer getNum() {
        return num;
    }
 
    /**
     * @param num the num to set
     */
    public void setNum(Integer num) {
        this.num = num;
    }
 
    /**
     * @return the wineyear
     */
    public Integer getWineyear() {
        return wineyear;
    }
 
    /**
     * @param wineyear the wineyear to set
     */
    public void setWineyear(Integer wineyear) {
        this.wineyear = wineyear;
    }
 
    public int hashCode() {
        int result = 0;
        if(this.num != null){
            result = this.num.hashCode();
        }
        if(this.getWineyear() != null){
            result = result*7 + this.getWineyear().hashCode();
        }
        return result;
    }
 
    @Override
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (obj == null) return false;
        if (!(obj instanceof WineBottlePK)) return false;
 
        WineBottlePK pk = (WineBottlePK) obj;        
 
        if(this.num.equals(pk.num) && this.getWineyear().equals(pk.getWineyear())){
            return true;
        }
        return false;
    }
 
 
}

Main.java

package hibernatesample;
 
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class Main {
 
    private static final Log log = LogFactory.getLog(Main.class);
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("HibernateSamplePU");
        EntityManager em = emf.createEntityManager();
        EntityTransaction transaction = em.getTransaction();
 
 
        transaction.begin();
        WineBottle bottle = new WineBottle();
        bottle.setLabel("mylabel");
        bottle.setNum(45);
        bottle.setWineyear(1975);
 
        em.persist(bottle);
 
        transaction.commit();
 
        WineBottlePK pk = new WineBottlePK();
        pk.setNum(45);
        pk.setWineyear(1975);
 
        WineBottle bottlefound = em.find(WineBottle.class, pk);
        log.info(bottlefound.getLabel());
 
        em.close();
    }
 
}

Mapped superclasses

Mapped Superclasses haben keine Tabelle. Die Attribute werden in der Tabelle der Subklasse integriert.

Employee:

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@MappedSuperclass
public class Employee  implements Serializable {
 
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
 
    @Version
    private Integer version;
 
    @Basic
    private String name;
 
    /**
     * @return the id
     */
    public Integer getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Integer id) {
        this.id = id;
    }
 
    /**
     * @return the version
     */
    public Integer getVersion() {
        return version;
    }
 
    /**
     * @param version the version to set
     */
    public void setVersion(Integer version) {
        this.version = version;
    }
 
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }
 
    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
 
}

Soldier:

package hibernatesample;
 
import javax.persistence.*;
 
@Entity
@AttributeOverride(name="name", column=@Column(name="SOLDIER_NAME"))
public class Soldier extends Employee {
 
    @Column(name="WEAPON")
    private String mainWeapon;
 
    /**
     * @return the mainWeapon
     */
    public String getMainWeapon() {
        return mainWeapon;
    }
 
    /**
     * @param mainWeapon the mainWeapon to set
     */
    public void setMainWeapon(String mainWeapon) {
        this.mainWeapon = mainWeapon;
    }
 
}

Beispielprogramm:

package hibernatesample;
 
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
public class Main {
 
    private static final Log log = LogFactory.getLog(Main.class);
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("HibernateSamplePU");
        EntityManager em = emf.createEntityManager();
        EntityTransaction transaction = em.getTransaction();
 
 
        transaction.begin();
 
 
        Soldier s = new Soldier();
 
        s.setMainWeapon("Spear");
        s.setName("orlando");
        em.persist(s);
 
        transaction.commit();
 
        em.close();
    }
 
}

Entity Listeners

Folgende Listeners können definiert werden:

  • @PrePersist Executed before the entity manager persist operation is actually executed or cascaded. This call is synchronous with the persist operation.
  • @PreRemove Executed before the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation.
  • @PostPersist Executed after the entity manager persist operation is actually executed or cascaded. This call is invoked after the database INSERT is executed.
  • @PostRemove Executed after the entity manager remove operation is actually executed or cascaded. This call is synchronous with the remove operation.
  • @PreUpdate Executed before the database UPDATE operation.
  • @PostUpdate Executed after the database UPDATE operation.
  • @PostLoad Executed after an entity has been loaded into the current persistence context or an entity has been refreshed.

Simple Entity;

package hibernatesample;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
 
@Entity()
@Table(name = "simpleentity")
@EntityListeners(SimpleEntityListener.class)
public class SimpleEntity {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "acolumn")
    private String aString;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the aString
     */
    public String getAString() {
        return aString;
    }
 
    /**
     * @param aString the aString to set
     */
    public void setAString(String aString) {
        this.aString = aString;
    }
 
}



Listener:

package hibernatesample;
 
import javax.persistence.PrePersist;
 
 
public class SimpleEntityListener {
 
      @PrePersist
      public void updateUser(Object o) {
        System.out.println("persisting object");
      }
 
}

Mapped Key

package hibernatesample;
 
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.*;
 
@Entity()
@Table(name = "project")
public class Project implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    private String projectName;
 
    @OneToMany(mappedBy="project", cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @MapKey(name="id")
    private Map<Long, ProjectMember> members = new HashMap<Long, ProjectMember>();
 
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the projectName
     */
    public String getProjectName() {
        return projectName;
    }
 
    /**
     * @param projectName the projectName to set
     */
    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }
 
    /**
     * @return the members
     */
    public Map<Long, ProjectMember> getMembers() {
        return members;
    }
 
    /**
     * @param members the members to set
     */
    public void setMembers(Map<Long, ProjectMember> members) {
        this.members = members;
    }
 
}
 
 
package hibernatesample;
 
import javax.persistence.*;
 
@Entity()
@Table(name = "projectmember")
public class ProjectMember {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    private String memberName;
 
    @ManyToOne(optional=false, fetch = FetchType.EAGER)
    @JoinColumn(name="projectid", nullable=false)
    private Project project;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the memberName
     */
    public String getMemberName() {
        return memberName;
    }
 
    /**
     * @param memberName the memberName to set
     */
    public void setMemberName(String memberName) {
        this.memberName = memberName;
    }
 
    /**
     * @return the project
     */
    public Project getProject() {
        return project;
    }
 
    /**
     * @param project the project to set
     */
    public void setProject(Project project) {
        this.project = project;
    }
 
}
 
/*
 * 
 */
 
package hibernatesample;
 
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
/**
 *
 * @author Claude Glauser
 */
public class Main {
 
    private static final Log log = LogFactory.getLog(Main.class);
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("HibernateSamplePU");
        EntityManager em = emf.createEntityManager();
        EntityTransaction transaction = em.getTransaction();
 
 
        transaction.begin();
 
        Project p = new Project();
        p.setProjectName("myproject");
        ProjectMember member = new ProjectMember();
        member.setMemberName("sfsd");
        member.setProject(p);
 
        em.persist(p);
        em.persist(member);
 
 
        transaction.commit();
 
        em.close();
    }
 
}

Mapping in XML anstatt Annotationen

Das Schema für das Mapping: http://java.sun.com/xml/ns/persistence/orm_1_0.xsd

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
 
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="1.0"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
		http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
 
    <persistence-unit name="person" transaction-type="RESOURCE_LOCAL">
 
        <provider>
            org.hibernate.ejb.HibernatePersistence
        </provider>
 
        <mapping-file>
        	META-INF/mymapping.xml
        </mapping-file>
        <mapping-file>
        	META-INF/mymapping2.xml
        </mapping-file>
 
 
        <properties>            
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
        </properties>
    </persistence-unit>
</persistence>


Die Datei mymapping.xml im META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
	version="1.0">
 
	<entity class="demo.MyEntity" access="FIELD" metadata-complete="true">
		<table name="SAMPLE"></table>
		<inheritance strategy="SINGLE_TABLE"/>
		<discriminator-column name="DISCRIMINANT" length="1"/>
		<attributes>
			<basic name="firstname">
				<column name="FIRSTNAME"/>
			</basic>
			<transient name="ticket"/>
		</attributes>
	</entity>
 
</entity-mappings>

Inheritance

Default Inheritance Strategy ist SINGLE_TABLE.

SINGLE_TABLE

InheritanceTestRoot.java:

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "ihtestroot")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING,length=150)
@DiscriminatorValue("ROOT")
public class InheritanceTestRoot implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "testRootText")
    private String testRootText;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the testRootText
     */
    public String getTestRootText() {
        return testRootText;
    }
 
    /**
     * @param testRootText the testRootText to set
     */
    public void setTestRootText(String testRootText) {
        this.testRootText = testRootText;
    }
}

InheritanceTestFirst.java

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@DiscriminatorValue("FIRST")
public class InheritanceTestFirst extends InheritanceTestRoot implements Serializable {
 
 
 
    @Column(name = "firsttext")
    private String testFirstText;
 
 
 
    /**
     * @return the testFirstText
     */
    public String getTestFirstText() {
        return testFirstText;
    }
 
    /**
     * @param testFirstText the testFirstText to set
     */
    public void setTestFirstText(String testFirstText) {
        this.testFirstText = testFirstText;
    }
 
 
}

InheritanceTestSecond.java

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@DiscriminatorValue("SECOND")
public class InheritanceTestSecond extends InheritanceTestFirst implements Serializable {
 
 
    @Column(name = "secondtext")
    private String testSecondText;
 
 
    /**
     * @return the testSecondText
     */
    public String getTestSecondText() {
        return testSecondText;
    }
 
    /**
     * @param testSecondText the testSecondText to set
     */
    public void setTestSecondText(String testSecondText) {
        this.testSecondText = testSecondText;
    }
 
 
}

Erstellt eine Tabelle ihtestroot, obschon in den Subklassen Tabellen namen angegeben wurden.

JOINED

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "ihtestroot")
@Inheritance(strategy=InheritanceType.JOINED)
public class InheritanceTestRoot implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "testRootText")
    private String testRootText;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the testRootText
     */
    public String getTestRootText() {
        return testRootText;
    }
 
    /**
     * @param testRootText the testRootText to set
     */
    public void setTestRootText(String testRootText) {
        this.testRootText = testRootText;
    }
}
package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "ihtestfirst") //Wird bei Single_table ignoriert
public class InheritanceTestFirst extends InheritanceTestRoot implements Serializable {
 
 
 
    @Column(name = "firsttext")
    private String testFirstText;
 
 
 
    /**
     * @return the testFirstText
     */
    public String getTestFirstText() {
        return testFirstText;
    }
 
    /**
     * @param testFirstText the testFirstText to set
     */
    public void setTestFirstText(String testFirstText) {
        this.testFirstText = testFirstText;
    }
 
 
}
package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "ihtestsecond") //Wird bei Single_table ignoriert
public class InheritanceTestSecond extends InheritanceTestFirst implements Serializable {
 
 
    @Column(name = "secondtext")
    private String testSecondText;
 
 
    /**
     * @return the testSecondText
     */
    public String getTestSecondText() {
        return testSecondText;
    }
 
    /**
     * @param testSecondText the testSecondText to set
     */
    public void setTestSecondText(String testSecondText) {
        this.testSecondText = testSecondText;
    }
 
 
}

Die generierten Tabellen

  • IHTESTROOT (id, testroottext), kein Foreignkey
  • IHTESTFIRST (id, firsttext), ForeignKey auf IHTESTOOT->ID
  • IHTESTSECOND (id, secondtext), ForeignKey auf IHTESTFIRST->ID

TABLE_PER_CLASS

Table per Class ist wie JOINED, nur dass alle Attribute in den Tabellen vorhanden sind, nicht nur die von den jeweiligen Klassen. Enthalt also keine FKs in den Tabellen wegen Inheritance. Die Annotation @GeneratedValue im Attribut id musste ich in der Superklasse entfernen.

Eine Entität wird in genau einer Tabelle gespeichert.

InheritanceTestRoot.java

package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "ihtestroot")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class InheritanceTestRoot implements Serializable {
 
    @Id
    @Column(name = "id")
    //@GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Column(name = "testRootText")
    private String testRootText;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the testRootText
     */
    public String getTestRootText() {
        return testRootText;
    }
 
    /**
     * @param testRootText the testRootText to set
     */
    public void setTestRootText(String testRootText) {
        this.testRootText = testRootText;
    }
}


InheritanceTestFirst.java:


package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "ihtestfirst") //Wird bei Single_table ignoriert
public class InheritanceTestFirst extends InheritanceTestRoot implements Serializable {
 
 
 
    @Column(name = "firsttext")
    private String testFirstText;
 
 
 
    /**
     * @return the testFirstText
     */
    public String getTestFirstText() {
        return testFirstText;
    }
 
    /**
     * @param testFirstText the testFirstText to set
     */
    public void setTestFirstText(String testFirstText) {
        this.testFirstText = testFirstText;
    }
 
 
}
package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
 
@Entity()
@Table(name = "ihtestsecond") //Wird bei Single_table ignoriert
public class InheritanceTestSecond extends InheritanceTestFirst implements Serializable {
 
 
    @Column(name = "secondtext")
    private String testSecondText;
 
 
    /**
     * @return the testSecondText
     */
    public String getTestSecondText() {
        return testSecondText;
    }
 
    /**
     * @param testSecondText the testSecondText to set
     */
    public void setTestSecondText(String testSecondText) {
        this.testSecondText = testSecondText;
    }
 
 
}
  • IHTESTROOT (ID, TESTROOTTEXT), keine FKs
  • IHTESTFIRST (ID, TESTROOTTEXT, FIRSTTEXT), keine FKs
  • IHTESTSECOND (ID, TESTROOTTEXT, FIRSTTEXT, SECONDTEXT), keine FKs

Pessimistic Locking

Die geneireirten SQLs für LockModeType.WRITE und LockModeType.READ sind für Derby-DB identisch.

READ Lock

EntityTransaction transaction = em.getTransaction();
transaction.begin();
Member newMemeber = em.find(Member.class, 1);
em.lock(newMemeber, LockModeType.READ);
transaction.commit();

Folgendes SQL wird für DerbyDB generiert:

SELECT id FROM mymember WHERE id =? FOR READ ONLY WITH rs

WRITE Lock

EntityTransaction transaction = em.getTransaction();
transaction.begin();
Member newMemeber = em.find(Member.class, 1);
em.lock(newMemeber, LockModeType.WRITE);
transaction.commit();

Folgendes SQL wird für DerbyDB generiert:

SELECT id FROM mymember WHERE id =? FOR READ ONLY WITH rs


Derby Isolation Levels

  • RR: SERIALIZABLE
  • RS: REPEATABLE
  • CS: READ COMMITTED
  • UR: READ UNCOMMITTED

Siehe [1]

Native Queries

Main.java

package hibernatesample;
 
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityResult;
import javax.persistence.EntityTransaction;
import javax.persistence.FieldResult;
import javax.persistence.LockModeType;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.SqlResultSetMapping;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
 
 
public class Main {
 
    private static final Log log = LogFactory.getLog(Main.class);
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("HibernateSamplePU");
        EntityManager em = emf.createEntityManager();
        EntityTransaction transaction = em.getTransaction();
 
 
        transaction.begin();
 
 
        //Query q = em.createNativeQuery("select name as itemname, descr as itemdescription from Item", "getItem");
 
        HugeObject ho = new HugeObject();
        ho.setName1("Nick");
        ho.setName2("Tina");
        ho.setName3("Rita");
        em.persist(ho);
 
        Long id = ho.getId();
 
        em.flush();
 
        Query query = em.createNativeQuery("select id, name1 as name_2, name2 as name_2, name3 as name_3 from primtable where id=?", "myMapping");
        query.setParameter(1, id);
        ho = (HugeObject) query.getSingleResult();
 
        transaction.commit();
 
 
 
        em.close();
    }
 
}


HugeObject.java


package hibernatesample;
 
import java.io.Serializable;
import javax.persistence.*;
 
@SqlResultSetMapping(
  name="myMapping",
  entities =@EntityResult(
    entityClass=HugeObject.class,
        fields= {
            @FieldResult(name="id", column="id"),
            @FieldResult(name="name1", column="name_1"),
            @FieldResult(name="name2", column="name_2"),
            @FieldResult(name="name3", column="name_3")
        }
    )
)
@Entity
@Table(name="PRIMTABLE")
public class HugeObject implements Serializable {
 
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
 
    @Basic
    @Column(name="name1")
    private String name1;
 
    @Basic
    @Column(name="name2")
    private String name2;
 
    @Basic
    @Column(name="name3")
    private String name3;
 
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
 
    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }
 
    /**
     * @return the name1
     */
    public String getName1() {
        return name1;
    }
 
    /**
     * @param name1 the name1 to set
     */
    public void setName1(String name1) {
        this.name1 = name1;
    }
 
    /**
     * @return the name2
     */
    public String getName2() {
        return name2;
    }
 
    /**
     * @param name2 the name2 to set
     */
    public void setName2(String name2) {
        this.name2 = name2;
    }
 
    /**
     * @return the name3
     */
    public String getName3() {
        return name3;
    }
 
    /**
     * @param name3 the name3 to set
     */
    public void setName3(String name3) {
        this.name3 = name3;
    }
 
}

Query samples

Einfaches query

SELECT x FROM Team x

Kartesisches Produkt

SELECT x, y FROM Team as x, Member as y
Query q = em.createQuery("SELECT x, y FROM Team as x, Member as y");
List objects = q.getResultList();

Die Objekte in der Liste sind vom Typ Object[]. Die Arrays haben immer eine länge von 2 mit einem Team und einem Member Objekt.


Left outer join

select t, m from Team as t left outer join t.members as m

Die Elemente in der Liste sind vom Typ Object[] mit je einem paar Team und Member.

Criteria API JPA 2.0

EntityManagerFactory emf = Persistence.createEntityManagerFactory("JavaApplication2PU");
 
EntityManager em = emf.createEntityManager();
 
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Entity1> q = cb.createQuery(Entity1.class);
Root<Entity1> root = q.from(Entity1.class);
Parameter<String> param =  cb.parameter(String.class, "firstname");
q.select(root).where(cb.equal(root.get(Entity1_.firstname), param));
 
 
Query query = em.createQuery(q);
query.setParameter(param, "Donald");
 
List<Entity1> res = query.getResultList();
for(Entity1 ent : res)
{
  System.out.print(ent);
}
em.close();

Resourcen