Membuat Aplikasi CRUD MySQL Dalam 10 Menit Dengan Griffon


Panduan video untuk artikel ini dapat dilihat di http://www.screencast.com/t/Mq254iDAr.

Griffon membuat pengembangan presentation layer menjadi mudah dan cepat.   Tapi untuk bagian persistence layer, Griffon masih belum seperti Grails yang menyediakan dynamic finders, scaffolding, dan fitur lainnya.   Padahal, developer seperti saya yang masih betah memakai Swing (belum beralih ke Java FX) sangat mengharapkan Griffon memiliki fitur serupa.  Saya juga tidak keberatan memakai Groovy yang ‘agak berat’ karena performance dan scalability umumnya tidak menjadi masalah bagi aplikasi desktop asalkan dijalankan di komputer dengan spesifikasi yang normal (bukan thin-client).

Sembari menunggu Griffon memiliki fitur seperti yang ada di Grails, saya mengembangkan sebuah plugin bernama simple-jpa  yang sementara ini akan saya pakai bersamaan dengan Griffon.  Tujuan utama plugin simple-jpa adalah mempermudah saya dalam mengembangkan aplikasi sehari-hari yang melakukan operasi database dengan JPA.  Caranya adalah dengan menyediakan dynamic finders, fasilitas scaffolding, validasi dengan Hibernate Validator, manajemen transaksi, auditing, soft-delete, template string untuk komponen Swing, dan sebagainya.

Untuk mendemokan cara kerja simple-jpa, saya akan membuat sebuah aplikasi sederhana yang terdiri atas dua domain class.  Btw, saya sangat senang dengan metode analisa berbasis domain (domain driven design), seperti yang saya tulis di Merancang Sistem Dengan UML: Mulai Dari Mana?.  Anggap saja aplikasi yang akan saya buat disini terdiri atas 2 domain class, yaitu Mahasiswa dan Matakuliah.   Kedua domain class tersebut memiliki hubungan many-to-many.

Langkah 1: Install Plugin simple-jpa

Setelah membuat sebuah proyek Griffon baru, saya harus men-install plugin simple-jpa dengan memberikan perintah berikut ini:

griffon install-plugin simple-jpa

Pastikan komputer terhubung ke Internet karena Griffon akan men-download dependency file JAR yang dibutuhkan oleh simple-jpa.  Plugin ini memiliki cukup banyak dependencyke library yang umum saya pakai, misalnya driver JDBC MySQL, Hibernate JPA, Hibernate Validator, Jadira User Type, Joda Time, SwingX, MigLayout, Glazed List dan sebagainya.  Tujuan utama simple-jpa menyertakan banyak dependency adalah agar penggunanya bisa langsung mulai membuat kode program tanpa harus dipusingkan dengan pengaturan dependency (bagi saya, ini berarti saya harus mencari2 di repo Maven).

Langkah 2:  Berikan perintah create-simple-jpa

Men-setup sebuah proyek untuk memakai JPA berarti harus membuat persistence.xml dan mengatur database.  simple-jpa menyederhanakan proses ini dengan menyediakan perintah create-simple-jpa yang terlihat seperti berikut ini:

griffon create-simple-jpa --user=snake --password=12345 --database=latihan --rootPassword=password

Saat ini, perintah create-simple-jpa hanya mendukung database MySQL.  Perintah tersebut selain membuat isi persistence.xml, juga akan membuat user dengan nama & password serupa dan database baru di  server MySQL yang sedang aktif di komputer lokal (localhost).  Karena itu, perintah ini membuat password root untuk server MySQL.  Password root tidak akan disimpan atau dipakai di kode program, melainkan hanya dibutuhkan untuk membuat user dan database baru.

Bila tidak memakai database MySQL, atau bila ingin melewatkan proses membuat user/database secara otomatis (misalnya karena sudah dibuat sebelumnya), maka tambahkan --skip-database=true sehingga perintah akan terlihat seperti:

griffon create-simple-jpa --user=snake --password=12345 --database=latihan --skip-database=true

Langkah 3:  Membuat domain class

Plugin simple-jpa dapat menghasilkan template untuk JPA entity selaku domain class melalui perintah create-domain-class.  Sebagai contoh, saya akan membuat domain class Mahasiswa dan Matakuliah secara bersamaan dengan menggunakan perintah berikut ini:

griffon create-domain-class Mahasiswa Matakuliah

Perintah di atas akan menghasilkan dua buah file di folder src/main/domain, yaitu Mahasiswa.groovy dan Matakuliah.groovy.  Saya perlu menambahkan atribut untuk domain class tersebut.  Karena mereka adalah JPA entity biasa, maka saya dapat menggunakan annotation JPA seperti biasanya.

Saya mengubah isi Mahasiswa.groovy menjadi seperti berikut ini:

package domain
import ... (diabaikan)

@DomainModel @Entity
@TupleConstructor @ToString
class Mahasiswa {

   @Size(min=2, max=10)
   String nim

   @Size(min=3, max=100)
   String nama

   @ManyToMany
   List<Matakuliah> listMatakuliah
}

Saya juga mengubah isi Matakuliah.groovy menjadi seperti berikut ini:

package domain
import ... (diabaikan)

@DomainModel @Entity
@TupleConstructor @ToString
class Matakuliah {

   @Size(min=2, max=2)
   String kode

   @Size(min=3, max=50)
   String nama

}

Pada plugin simple-jpa, setiap domain class harus memiliki annotation @DomainModel.   Selain itu untuk saat ini (rilis 0.1.3), atribut pertama yang didefinisikan di domain class akan dianggap sebagai natural primary key.   Plugin simple-jpa secara otomatis akan menambahkan id yang akan di-isi secara otomatis sebagai surrogate primary key.

Langkah 4: Menghasilkan MVC dari domain class (proses scaffolding)

Plugin simple-jpa dapat menghasilkan sebuah MVCGroup yang berisi operasi CRUD untuk sebuah domain class.  Btw, proses ini dinamakan sebagai scaffolding karena tujuannya adalah hanya membantu mempercepat proses pengembangan.  Developer tetap perlu mengubah isi MVCGroup tersebut, kecuali bila aplikasinya memang hanya melakukan operasi CRUD tanpa business logic.

Untuk menghasilkan MVCGroup untuk seluruh domain class yang ada, saya memberikan perintah generate-all seperti berikut ini:

griffon generate-all *

Setiap MVCGroup bisa dijalankan secara terpisah dan berdiri sendiri-sendiri.  Tetapi pada kenyataannya, biasanya MVCGroup yang ada perlu dikelompokkan ke dalam sebuah startup group atau yang menyerupai main di Java.  Saat ini belum ada panduan resmi dari Griffon, sehingga saya akan memakai style saya sendiri.  Untuk menghasilkan startup group yang akan dipakai untuk mengakses MVCGroup lain, saya memberikan perintah seperti berikut ini:

griffon generate-all --startup-group=StartupGroup

Berikutnya, saya perlu mengubah file Application.groovy agar menjadikan MVCGroup bernama StartupGroup sebagai startup group, seperti yang terlihat berikut ini:

application {
  title = 'Latihan'
  startupGroups = ['startupGroup']
}
mvcGroups {
  'startupGroup' { ... }
  'matakuliah' { ... }
  'mahasiswa' { ... }
}

Langkah 5: Menjalankan Aplikasi

Karena plugin simple-jpa mengatur persistence.xml agar membuat skema database secara otomatis (hal ini mempermudah dalam pengujian, tapi perlu diatur ulang saat produksi nanti), yang perlu saya lakukan berikutnya hanya menjalankan aplikasi.

MVCGroup StartupGroup akan dijalankan pertama kali dimana tampilannya akan terlihat seperti pada gambar berikut ini:

Tampilan StartupGroup

Tampilan StartupGroup

Bila saya men-klik tombol Matakuliah, saya dapat mengisi data matakuliah seperti yang terlihat pada gambar berikut ini:

Tampilan MVCGroup Matakuliah

Tampilan MVCGroup Matakuliah

Hasil scaffolding juga telah dilengkapi dengan validasi, seperti yang terlihat pada gambar berikut ini:

Hasil Scaffolding Dilengkapi Validasi

Hasil Scaffolding Dilengkapi Validasi

Bila saya men-klik tombol Mahasiswa, saya dapat mengisi data mahasiswa seperti yang terlihat pada gambar berikut ini:

Mengisi Data Mahasiswa

Mengisi Data Mahasiswa

Perhatikan bahwa nilai objek Matakuliah di tabel maupun di tag chooser terlihat cukup mengganggu (hasil dari toString()). Beruntungnya, plugin simple-jpa memiliki fitur string template yang mempermudah dalam mengatur seperti apa ‘tampilan’ sebuah objek.    Untuk itu, saya membuka file Mahasiswa.view, kemudian mengubah bagian definisi table() menjadi seperti berikut ini:

table(...) {
  eventTableModel(list: model.mahasiswaList,
    columnNames: ['Nim', 'Nama', 'Matakuliah Diambil'],
    columnValues: ['${value.nim}', '${value.nama}', '<% out << value.listMatakuliah?.collect{it.nama}?.join(", ") %>'])
  table.selectionModel = model.mahasiswaSelection
}

Saya juga mengubah bagian definisi tagChooser() sehingga menjadi seperti berikut ini:

tagChooser(model: model.listMataKuliah, templateString: '${value.kode} - ${value.nama}', ...)

Sekarang, bila saya mengisi data Mahasiswa, tampilan akan terlihat seperti berikut ini:

Tampilan Data Mahasiswa Setelah Memakai String Template

Tampilan Data Mahasiswa Setelah Memakai String Template

Perihal Solid Snake
I'm nothing...

19 Responses to Membuat Aplikasi CRUD MySQL Dalam 10 Menit Dengan Griffon

  1. Komang Hendra Santosa mengatakan:

    Wah, bagus nih mas..

    Ini brarti dy memanipulasi StartupGroupView ya mas..

    Maksudnya si StartupGroupView yg jadi penopangnya sedangkan view yg lain dimasukkan melalui id: “mainPanel” di StartupGroupView. Untuk databasenya sudah digenerate secara otomatis ma JPAnya jd tidak perlu susah membuatnya, kita cuma tinggal menambahkan di domain. Tp jika kita melakukan kesalahan pengisian pada domain itu maka yg lainnya juga ikut salah ya mas, karna kita buatnya dengan memakai scaffolding, jd mesti hati2 juga..Btw, untuk database ketika program dijalankan ulang dy akan secara otomatis menghapus semua isi tabel, tp kita bisa edit di persistence.xml di name=”hibernate.hbm2ddl.auto” kita ubah valuenya jadi value=”” jadi data yg sebelumnya diinput masih ada disana.

    Nah, untuk operasi CRUD, yg jadi masalah ketika mengubah nim dan kode, kalau pada tutorial mas yg CRUD kan ketika nimnya sama maka dy akan melakukan update dan ketika berbeda akan melakukan penambahan, di simple JPA sendiri apakah ada pengaturannya mas?Dan bisakah pada saat kita memilih dropdown list kita pilih satu saja, maksudnya tinggal pilih 1 tanpa menekan tombol tambah?kalo ga salah dy pake tagChooser, apa bisa diganti dengan yang biasa mas?

    • Solid Snake mengatakan:

      Yup, baris “hibernate.hbm2ddl.auto” hanya untuk membantu mempercepat proses pengujian, setelah dijalankan, boleh dihapus atau diberi komentar.

      Simple JPA secara otomatis akan menambahkan primary key berupa id yang akan diisi secara otomatis (memakai surrogate primary key). Hal ini tidak dapat dikonfigurasi. Akan tetapi hasil scaffolding tetap bisa di-update secara manual. Bila ingin mengubah template scaffolding, saat ini hanya bisa dengan mengubah source plugin tersebut di package simplejpa.templates.artifacts.

      Untuk memilih hanya satu pilihan, bisa memakai node comboBox() dari Swing. Tambahan dari Simple JPA adalah template string seperti:

      comboBox(model: model.selectedMatakuliah, renderer: listCellRenderer(template: ‘${value?.type} – ${value?.nama}’))

      Bila tidak ingin memakai plugin tersebut, bisa meniru pola hasil scaffolding yang ada (setiap domain class menghasil sebuah MVCGroup). Semoga bisa bermanfaat.

  2. Komang Hendra Santosa mengatakan:

    Maksud saya begini mas..Dropdown yg disana kan untuk mata kuliah, nah misal kalo dropdownnya untuk jenis makanan, misal Mie 1 pak, jadi kan kita milihnya Produk Mie truz di dropdown nanti kan ada bnyak list (galon, pak, dus, dll), nah kita hanya pilih 1 saja yaitu PCS – Packs dan tidak perlu ditambahkan tagChoosernya, pokoknya kita pakai dropdown gt mas, itu bagaimana mas?perlu ganti kodenya dimana?

    Mohon pencerahannya..

    • Solid Snake mengatakan:

      Jika saya tidak salah mengerti, yang dimaksud adalah hubungan Many-To-One atau One-To-One (sementara TagChooser untuk hubungan Many-To-Many)? Bila iya, biasanya memakai JComboBox biasa. Apakah yang dimaksud seperti ini http://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html? Bila iya, gunakan comboBox() di view untuk menggantikan tagChooser(). Bila domain classnya adalah class Satuan { String singkatan; String namaLengkap }, maka definisinya bisa seperti berikut ini:

      comboBox(model: model.selectedSatuan, renderer: listCellRenderer(template: ‘${value?.singkatan} – ${value?.namaLengkap}’))

      Fasilitas scaffolding pada Simple JPA hanya nilai tambah untuk mempercepat proses pengembangan. Hasilnya seperti MahasiswaView, MahasiswaController, dan MahasiswaModel tetap perlu disesuaikan karena tidak semua aplikasi hanya CRUD biasa.

      Simpe JPA bisa dipakai tanpa harus melalui scaffolding; view, model, dan controller bisa dibuat secara manual. Fitur utama dari Simple JPA adalah di controller, bisa memakai dynamic finders, misalnya untuk men-query seluruh Mahasiswa yang bernama ‘Snake’ dan beralamat di ‘Indonesia’, pengguna bisa memberikan perintah: findMahasiswa([nama: ‘Snake’, alamat: ‘Indonesia’]), dsb.

  3. Komang Hendra Santosa mengatakan:

    Mas pada saat saya jalankan programnya muncul error seperti ini:

    No such property: template for class: groovy.swing.impl.ClosureRenderer

    codenya:

    comboBox(model: model.listMatakuliah, renderer: listCellRenderer(template: ‘${value.?kode} – ${value.?nama}’))

    saya masih pakai yg mas punya..itu propertinya ga ada ya mas?

    • Solid Snake mengatakan:

      Kamu harus melakukan perubahan di view, model, dan domain model. Cara tercepat dan termudah adalah dengan membuka Mahasiswa.groovy di package domain, kemudian cari:

      @ManyToMany
      List<Matakuliah>  listMatakuliah  // menampung lebih dari satu
      

      dan ubah menjadi:

      @ManyToOne
      Matakuliah matakuliah  // menampung hanya satu
      

      Kemudian hapus MahasiswaView, MahasiswaController dan MahasiswaModel, selain itu, juga buka file Application.groovy, pada bagian mvcGroups { }, hapus bagian 'mahasiswa' { ... }.

      Setelah itu, berikan perintah generate-all Mahasiswa. Simple JPA secara otomatis akan menghasilkan view yang memakai comboBox() bila mendeteksi hubungan ManyToOne ataupun OneToOne.

      Kemudian, gunakan tools favorit untuk menghapus seluruh tabel yang telah di-generate sebelumnya. Bila memakai MySQL client, berikan perintah:

      C:> mysql -u root -ppassword
      mysql> use latihan;
      mysql> drop table mahasiswa_matakuliah;
      mysql> drop table mahasiswa;
      mysql> drop table matakuliah;
      

      Jalankan aplikasi, kali ini matakuliah akan berupa JComboBox.

  4. Great work! I wonder if you would like to publish simple-jpa to http://artifacts.griffon-framework.org; in this way more people will know about it and you may have more feedback😀

    Cheers,
    Andres

  5. Developer membership granted🙂 Feel free to push a release any time.

  6. Komang Hendra Santosa mengatakan:

    Siip mas, udah jalan.. ternyata enak jg nih pakainya, cuman kita mesti edit2 template viewnya aja..

    Wah.. Selamat ya mas..Sudah masuk jd developernya griffon..
    Saya tunggu perkembangan pluginnya mas😀

    Pembuat griffonnya aja mpe kesini main, hehe..

    Keep the Great work!

    I’ll keep track on your tutorials😀

  7. Komang Hendra Santosa mengatakan:

    Mas, untuk validator sendiri apakah di simple jpa ada selain untuk string?
    seperti tanggal, email, angka, dll..Jika ada perintahnya apa di domain class itu mas?

  8. Komang Hendra Santosa mengatakan:

    Buat aja dokumentasinya mas, biar gampang pakainya..

    Mas, klo di simple jpa, bs ga kita mengupdate 2 tabel secara bersamaan?
    misal kita melakukan penyimpanan, ada tabel pembelian dan detailpembelian dalam 1 form, kita ingin update tabel2 tersebut secara terpisah dalam 1 kali penyimpanan, kira2 gmn ya mas?
    dan dimana skrip SQL dijalankan?pengen liat sintaksnya, apa bisa dibuat manual ya?

    O ya, kalo di list data tabel bisa dibuatin kaya zebra(putih, abu) gt ga mas?soalnya yg ini putih semua, defaultnya kan data dalam table itu zebra, tp kok putih ya?

    O ya, saya jg kedapatan error sewaktu memakai datetime di domain.

    codenya di view seperti ini:

    label(‘Tanggal:’)
    jxdatePicker(id: ‘tanggal’, date: bind(‘tanggal’, target: model, converter: { it==null?null:new DateTime(it) },
    reverseConverter: { it==null?null:((DateTime)it)?.toDate() }, mutual: true), errorPath: ‘tanggal’)
    errorLabel(path: ‘tanggal’, constraints: ‘wrap’)

    errornya:

    groovy.lang.MissingPropertyException: No such property: editor.background for class: org.jdesktop.swingx.JXDatePicker

    ini maksudnya apa ya mas?efeknya semua textfield pun tidak bisa diinput.

    • Solid Snake mengatakan:

      simple-jpa memakai JPA yang memetakan object ke dalam tabel. Developer hanya perlu berhubungan dengan object dan JPA yang akan memetakan (termasuk menghasilkan SQL). Jika sebuah objek mengandung hubungan ke objek lain, selama nilainya sudah di-isi, saat memberikan `persist(object)` atau `merge(object)` di controller, maka tabel yang bersesuaian akan di-update secara otomatis. Saya akan mencoba mendokumentasikan method yang tersedia di post selanjutnya.

      JPA adalah bagian dari Java, saya hanya memakai salah satu implementasi spesifikasi JPA, yaitu Hibernate. Source yang mengerjakan SQL ada di Hibernate. simple-jpa tetap memungkinkan kamu mengerjakan SQL secara manual, dengan memberikan perintah `executeNativeQuery()` dan mengerjakan JP QL dengan perintah `executeQuery()`.

      Untuk membuat table yang ada zebra-nya, kamu bisa mengubah kode program view yang membuat node `table()` menjadi memakai `jxtable()` seperti berikut ini:

      jxtable(rowSelectionAllowed: true, id: 'table', 
         highlighters: HighlighterFactory.createAlternateStripping()) {
        ...
      }
      

      Kamu juga bisa menentukan sendiri warna stripping, misalnya:

      jxtable(rowSelectionAllowed: true, id: 'table', 
         highlighters: HighlighterFactory.createAlternateStripping(
            Color.LIGHT_GRAY, Color.YELLOW)) {
        ...
      }
      

      Terima kasih sudah mencoba dan memakai simple-jpa. Saya sudah memperbaiki kesalahan tersebut. Untuk memakai versi terbaru, uninstall plugin simple-jpa, kemudian berikan perintah berikut ini:

      install-plugin simple-jpa 0.1.3
      

      Pada versi terakhir ini, saya juga menambahkan hal baru seperti:

      Untuk menimpa MVCGroup yang telah dihasilkan sebelumnya, gunakan perintah seperti: generate-all Mahasiswa --force-overwrite. Dengan variasi perintah ini, kamu tidak perlu menghapus file MVC sebelum memberikan generate-all pada domain-class yang sudah pernah di-generate sebelumnya.

      Perintah baru install-templates akan membuat templates di folder src/templates/artifacts. Kamu bisa mengubah template view, model, dan controller yang akan dipakai oleh generate-all di folder ini.

  9. Komang Hendra Santosa mengatakan:

    mas gmn cranya mengubah setinggan datetime biar pas di MySQL dan di applikasinya sendiri?
    karena ketika saya add di app munculnya spt ini: 2013-04-05T00:00:00:000+08:00 dan pada MySQL sendiri seperti ini: 2013-04-04 16:00:00, aneh bgt..

    dan saya coba pake settingan datetime mas yg: DateTimeFormatter df = DateTimeFormat.forPattern(“dd-MM-yyyy”) itu error class DateTimeFormat not found, walau sudah saya import org.joda.time.*, tp belum saya lihat sih hasilnya karena error tsb.

    dan saya jg coba menggunakan passwordField untuk textfield type password, ketika saya tidak input apa2 mestinya dy menampilkan pesan error, berikut kodenya:

    passwordField(id: ‘password’, columns: 15, text: bind(‘password’, target: model, mutual: true))
    errorLabel(path: ‘password’, constraints: ‘wrap’)

    domain classnya:

    @Size(min=4, max=15)
    String password

    kalau kita ganti pake textField errornya bisa muncul, nah gmn dengan passwordFieldnya..

    untuk jxtable sendiri, ketika saya pakai highlighternya, muncul error:

    No such property: HighlighterFactory for class: org.codehaus.griffon.runtime.builder.UberBuilder

    format saya seperti ini:

    jxtable(rowSelectionAllowed: true, id: ‘table’, highlighters: HighlighterFactory.createAlternateStripping()) {
    eventTableModel(list: model.userList,
    columnNames: [‘User ID’, ‘Username’, ‘Password’, ‘Level’],
    columnValues: [‘${value.userID}’, ‘${value.username}’, ‘${value.password}’, ‘${value.level}’])
    table.selectionModel = model.userSelection
    }

    Mas, tahu caranya mengenerate id dalam hal ini no nota, kode secara berurutan dan berdasarkan tanggal (BR001 – BR00xm dan NT00201304050001 – NT0020130405000x)?
    Maaf, kalau saya banyak bertanya mas..

    • simplejpa mengatakan:

      Menjawab pertanyaan pertama, itu adalah perilaku yang wajar untuk Joda Time (dokumentasi bisa dibaca di http://joda-time.sourceforge.net/userguide.html). DateTime menyimpan informasi TimeZone. Yang disimpan di database adalah nilai pada timezone UTC. Dengan demikian, pengguna dari negara yang memiliki TimeZone berbeda akan mendapatkan tampilan jam sesuai TimeZone mereka. Bila tidak ingin menyimpan informasi TimeZone, gunakan class LocalDate atau LocalDateTime.

      Untuk memakai DateTimeFormat, import class org.joda.time.format.DateTimeFormatter sementara kamu hanya men-import package org.joda.time.* (Java tidak akan men-import subpackage). Bila kamu sudah menyertakan dependency JAR joda-time-2.1.jar (file JAR tersebut ada di Ivy cache dan direktori staging), maka bisa memilih menu organize import dari IDE favoritmu.

      Untuk yang berhubungan dengan JPasswordField, itu adalah sebuah bug. Gunakan simple-jpa yang di-download dari lokasi berikut ini: https://docs.google.com/file/d/0B-_rVDnaVRCbbDZRUkFYN1lDRm8/edit?usp=sharing yang telah menyertakan perbaikan untuk bug tersebut. Btw, itu bukan versi rilis. Sebaiknya tunggu sampai di-rilis di portal. Jangan lupa menambahkan errorPath di passwordField().

      Untuk SwingX highlighters, apakah kamu telah men-import class HighlighterFactory? Kamu harus memberikan import org.jdesktop.swingx.decorator.HighlighterFactory. Seandainya kamu telah menyertakan dependency JAR swingx-core-1.6.4.jar, maka IDE-mu akan bisa men-import class secara otomatis.

      Untuk pertanyaan terakhir, salah satu solusinya untuk mendapatkan kode seperti “NT00201304050001”, “NT00201304050002”, dst adalah dengan kode program seperti berikut ini:

      String buatKode() {
         String tangal = DateTime.now().toString("yyyyMMdd")
         List list = findAllStok([orderBy: 'id', orderDirection: 'desc'])
         Integer angka = list.size()==0? 0: list[0].id     
         String.format("NT00%s%04d", tanggal, angka)
      }
      

      Karena id (primary key otomatis) bisa saja jadi tidak berurutan, maka alternatif lain yang mungkin adalah:

      String buatKode() {
         String tangal = DateTime.now().toString("yyyyMMdd")
         List list = findAllStok([orderBy: 'kode', orderDirection: 'desc'])
         Integer angka = list.size()==0? 0: list[0].kode[12..-1].toInteger() + 1
         String.format("NT00%s%04d", tanggal, angka)
      }
      ...
      Stok stok1 = new Stok(buatKode(), "CPU Intel Core i7")
      persist(stok1)
      commitTransaction()
      
      beginTransaction()
      Stok stok2 = new Stok(buatKode(), "Plantronics GameCom 780 7.1 Surround")
      persist(stok2)
      commitTransaction()
      ...
      

      Jangan lupa import-nya. Serta JAR joda time agar gampang.

      Kinerja bisa ditingkatkan dengan meminta simple-jpa hanya mengembalikan baris terakhir (limit). Tunggu rilis berikutnya🙂

      Btw, untuk pertanyaan lebih lanjut, coba daftar di https://groups.google.com/forum/?fromgroups#!forum/griffon-simple-jpa.

  10. Komang Hendra Santosa mengatakan:

    OK, sip lah mas, saya tunggu rilis berikutnya sambil coba2 skrip diatas, hehe..
    Untuk grupnya saya sudah daftar tinggal diapprove aja mas..

    Kabarin ya mas kalau udah rilis😀

  11. Komang Hendra Santosa mengatakan:

    Mas, saya belum paham nih mengenai Domain ini. Domain kan yg mengatur pembuatan tabel2 pada database, MVC dan validasi jg.

    Critanya saya pingin buat Domain Pembelian yg didalamnya terdapat entitiy sbg berikut: noNota, tanggal, kodeSupplier, total dan userID (yang nantinya dimasukkan ke dalam tabel pembelian), noNota, kodeBrg, jumlah dan harga (tabel detail pembelian), disamping itu untuk applikasinya sendiri kita membutuhkan isi dari tabel barang (kodeBrg, namaBrg, harga), jumlah, dan total untuk ditampilkan pada jxtable, user(userID), dan supplier(kodeSupplier). Apakah code Domain saya ini sudah benar mas?

    code:

    class Pembelian {
    @Size(min=5, max=25)
    String noNota

    @NotNull @Type(type=”org.jadira.usertype.dateandtime.joda.PersistentDateTime”)
    DateTime tanggal

    @NotNull @ManyToOne
    Supplier kodeSupplier

    @NotNull
    Integer total

    @NotNull @ManyToOne
    User userID

    @NotNull @ManyToOne
    Barang barang

    @NotNull
    Integer jumlah
    }

    class DetailPembelian {
    @Size(min=5, max=25)
    String noNota

    @Size(min=5, max=5)
    String kodeBrg

    @NotNull
    Integer jumlah

    @NotNull
    Integer harga
    }

    Mohon koreksinya mas..

    • Solid Snake mengatakan:

      Relasi antar kedua domain class tersebut adalah one-to-many, sehingga pada class Pembelian harus memiliki sebuah List yang menampung satu atau lebih DetailPembelian. Contoh pemetaan dapat dilihat di https://thesolidsnake.wordpress.com/2013/04/16/panduan-mapping-asosiasi-jpa/.

      Selain itu, tergantung pada proses bisnis, atribut total mungkin tidak perlu disimpan di tabel dan dapat dikalkulasi secara otomatis dengan membuat sebuah getter seperti getTotal() di domain class Pembelian. Akan tetapi, hal ini tidak berlaku bila total diperoleh dari hasil negosiasi dengan pelanggan (dengan nilai diskon yang bervariasi) sehingga harus disimpan ke dalam tabel.

Apa komentar Anda?

Please log in using one of these methods to post your comment:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: