OpenJPA

Dari IgosCenter

Langsung ke: Navigasi, Cari

OpenJPA adalah pustaka untuk pemrograman Java yang memungkinkan penyimpanan obyek ke database relasional biasa (persistence). Produk ini dibuat oleh Apache Foundation, merupakan rival dari [Toplink] yang dibuat oleh Oracle.

Daftar isi

Lisensi

OpenJPA dilepas dengan lisensi Apache License versi 2.0.

Mengunduh

Kunjungi situs OpenJPA di http://openjpa.apache.org/downloads.html. Berkas yang sebaiknya diunduh adalah:

  • apache-openjpa-VERSION-binary.zip
  • manual.pdf

Jika perlu, unduh juga kodesumbernya:

  • apache-openjpa-VERSION-source.zip

Memasang

Tinggal diekstrak, misal ke $HOME/java

$ cd $HOME
$ mkdir -p java
$ cd java
$ unzip $HOME/Download/apache-openjpa-VERSION-binary.zip

Pemakaian di Netbeans

Aslinya, Netbeans memakai Toplink Esential sebagai layanan persistence. Namun setelah digunakan untuk aplikasi desktop dengan arsitektur client-server, Toplink Esential belum mendukung cache-coordination (hanya didukung di Toplink 11g yang merupakan produk komersial), dan akibatnya fatal. Karena itu, migrasi ke OpenJPA menjadi keharusan. Berikut ini pengalaman ketika migrasi suatu aplikasi cukup besar yang sebelumnya sudah menggunakan Toplink ke OpenJPA.

Mendaftarkan Pustaka

Langkah pertama di Netbeans agar selanjutnya lebih mudah dipakai:

  • Pilih menu Tools - Libraries
  • Buatlah pustaka baru bernama OpenJPA (Klik tombol New Library).
  • Tambahkan pustaka OpenJPA (Pilih tab Classpath, lalu klik Add Jar/Folder).
  • Sebaiknya tambahkan juga Dokumentasi (Pilih tab Doc, lalu klik Add Zip/Folder

Berkas:Netbeans-LibraryManager-OpenJPA.png

Proyek Aplikasi Desktop Database

Jika proyek baru akan dibuat dari awal, pada Netbeans, ... (maaf belum nyoba).

Menambah Pustaka

Pada panel Project, pilih Proyek yang akan ditambahi OpenJPA

  • Klik kanan daun Libraries, pilih menu Add Libraries
  • Tambahkan OpenJPA

Berkas:Netbeans-AddLibrary-OpenJPA.png

Ganti Persistance

Edit file persistence.xml,

  • Ganti Persistence Library menjadi OpenJPA.

Aktifkan OpenJPA Enhancement

Edit file build.xml, tambahkan

    <target name="-post-compile">
        <echo message="begin openJPAC"/>
        <path id="openjpa.path.id">
            <pathelement location="${build.classes.dir}"/>

             <!-- Adding the OpenJPA jars into the classpath -->
            <!--fileset dir="/home/kocil/java/apache-openjpa-1.2.1/lib" includes="*.jar"/-->
             <!--  or if you created an OpenJPA Library you can use this instead  -->
            <pathelement path="${libs.OpenJPA.classpath}"/>
        </path>

        <taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask">
            <classpath refid="openjpa.path.id"/>
        </taskdef>

        <openjpac>
            <classpath refid="openjpa.path.id"/>
            <fileset dir=".">

                <include name="**/Entitas/*.java" />
            </fileset>
        </openjpac>
        <echo message="end openJPAC"/>
    </target>

Masalah Migrasi Toplink - OpenJPA

Ketika proyek yang sudah memakai Toplink dimigrasi ke OpenJPA, aduh mak, banyak sekali masalah yang muncul. Memecahkannya sangat makan waktu dan googling. So bilang trims berat untukku kalau tips-tips berikut menolongmu yach ;)

Version Pada Inheritance

Jika ada entitas yang memakai fitur Inheritance, dan pada ancestor maupun descendant ada field version (yang dipakai untuk fitur optimistic locking), maka akan timbul error saat kompilasi (hal ini tidak terdeteksi oleh Toplink). Solusinya, hapus field tersebut pada ancestor.

Multiple Primary Key

Jika ada entitas yang memakai multiple primary key, maka strategi JPA adalah membuatkan kelas baru (Misal jika ada kelas Akses, maka akan dibuatkan kelas AksesPK). Ketika proyek sudah dikompilasi dan dijalankan, pesan errornya kira-kira

Caused by: <openjpa-1.2.1-r752877:753278 fatal user error> org.apache.openjpa.persistence.ArgumentException: 
The type "class com.mydomain.entities.AksesPK" has not been enhanced."

Ada dua hal yang harus dikerjakan.

  • pastikan enhancement telah diaktifkan (lihat sebelumnya)
  • Edit persistence.xml secara manual (dalam mode XML), tambahkan semua kelas PK secara manual
<?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="RSHSPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <class>Entitas.Akses</class>
    <class>Entitas.AksesPK</class>
    <class>Entitas.Anggota</class>
    <class>Entitas.Kelompok</class>
    <class>Entitas.KelompokAnggota</class>
    <class>Entitas.KelompokAnggotaPK</class>
    <class>Entitas.Modul</class>
    <properties>
      <property name="openjpa.ConnectionPassword" value="password"/>
      <property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver"/>
      <property name="openjpa.ConnectionUserName" value="postgres"/>
      <property name="openjpa.ConnectionURL" value="jdbc:postgresql://localhost/RSHS"/>
      <property name="openjpa.jdbc.DBDictionary" value="postgres(StoreCharsAsNumbers=false)"/>
      <property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=true)"/>
    </properties>
  </persistence-unit>
</persistence>

Bad value for type BigDecimal

Jika ada entitas yang memakai tipe BigDecimal, akan muncul pesan error ini. Solusinya dengan menambah property pada persistence.xml

      <property name="openjpa.jdbc.DBDictionary" value="postgres(StoreCharsAsNumbers=false)"/>

Result lists are read-only

Error ini muncul setelah dijalankan (run time), pada layar GUI yang mengakses tabel memakai list. Untuk itu kembali ke layar desain GUI yang bersangkutan, lalu:

  • Pada tab Inspector, pilih Other Component
  • Untuk semua list, pada panel Properties centang modifiableWrapper.

Attempt to persist detached object

Error ini muncul ketika menyimpan entitas baru (insert record baru ke database). Untuk menghindari ini, pastikan saat membuat entitas baru untuk tidak menginisialisasi :

  • field yang menjadi @Id, dan di database memekai auto incerment
  • filed yang menjadi @Version (untuk optimistic locking).

Detected reentrant flush

Error ini bisa terjadi pada entitas dengan id bertipe IDENTITY (auto generate), karena optional diset false.

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    // @Basic(optional = false)    Jangan pakai ini !!
    @Column(name = "id")
    private Long id;

Encountered unmanaged object in persistent field "CLASS.FOREIGN_ID" during flush

Masalah reentrant flush lewat, error berikutnya muncul dengan petunjuk yang agak panjang:

Caused by: <openjpa-1.2.1-r752877:753278 nonfatal user error> org.apache.openjpa.persistence.InvalidStateException: Encountered unmanaged object in persistent field "Entitas.Konsole.idLokasi" during flush.  However, this field does not allow cascade persist. Set the cascade attribute for this field to CascadeType.PERSIST or CascadeType.ALL (JPA annotations) or "persist" or "all" (JPA orm.xml), or enable cascade-persist globally, or manually persist the related field value prior to flushing. You cannot flush unmanaged objects or graphs that have persistent associations to unmanaged objects

Tak yakin bahwa memakai CascadeType.PERSIST adalah jalan bijak, untuk membetulkan error ini, saya memilih jalan meyakinkan di program bahwa field Konsole.idLokasi sudah di-set dengan entitas Lokasi yang benar.

Locking

  • ) Maaf yah, artikel ini statusnya masih hacking ;)

Kontributor: Kocil

(c) Igos Center Bandung, 2009