Basic CRUD Web Aplikasi Menggunakan SpringFramework-MVC, Freemarker, Hibernate dan JPA - Spring Project Model Class

Article Index

Spring Project Model Class

Tentunya kita akan bertanya-tanya, sudah ada class repository interface untuk akses ke database kenapa masih diperlukan class Model? Class Model diperlukan untuk mengurangi beban pada class Controller, sehingga Controller tidak dipenuhi oleh source code validasi dan sebagainya yang mengakibatkan source code Controller sangat panjang dan tidak efisien.

JAVA sangat dikenal dengan OOP (Object Oriented Programming) yang terstruktur dan SpringFramework sangat dikenal dengan AOP (Aspect Oriented Programming) modelnya. Dengan kedua model programming tersebut, alur program dan object dependency menjadi lebih terstruktur dan efisien serta source code program menjadi lebih teratur.

Berikut ini adalah diagram alur yang menjelaskan secara umum hubungan antara: Model, Views, Controller, JPA-Repository dan JPA-Entity.

Dari diagram diatas dapat kita petik kesimpulan bahwa Controller membutuhkan Model untuk melakukan beragam aktifitasnya. Dan Model diperlukan karena ada beberapa hal yang tidak dapat dilakukan oleh Repository tetapi dapat dilakukan oleh Model.

Selanjutnya marilah kita membuat class Model untuk project web aplikasi JPA-CRUD.

Pada Project Explorer dibawah package org.fajarapps.jpacrud kita menemukan package domain.types. Ini mungkin akan menyulitkan bagi yang belum terbiasa menggunakan IntelliJ IDEA. Tetapi bagi yang sudah terbiasa, ini mungkin bukanlah masalah yang besar. Pilih package org.fajarapps.jpacrud dan pada popup menuitem: New -> Java Class buat class baru dengan nama: domain.DepartmentModel. Maka class baru tersebut akan kita jumpai tepat dibawah package org.fajarapps.jpacrud.domain. Ketik source code berikut untuk DepartmentModel.java.

package org.fajarapps.jpacrud.domain;

/* import ... tidak ditampilkan */

@Repository
@Transactional
public class DepartmentModel
{
    private final Logger logger = LogManager.getLogger(getClass());
    @Autowired
    private IDepartmentRepository repository;

    /**
     * Menambahkan record Department baru.
     *
     * @param entity Data department
     */
    public void create(Department entity) {
        Department result = repository.save(entity);
        logger.info("Creating Department entity with data: {}", result);
    }

    /**
     * Menghapus record Department dari database.
     *
     * @param id Department identity
     * @throws EntityNotFoundException
     */
    public void delete(Integer id) throws EntityNotFoundException {
        Department dept = repository.findOne(id);
        if (dept == null) {
            throw new EntityNotFoundException("entity.department.NotFound");
        }

        repository.delete(id);
        logger.info("A department entity have been deleted with data: {}", dept);
    }

    /**
     * Menghapus beberapa record Department dari database.
     *
     * @param ids Koleksi identity Department
     * @return Jumlah record yang berhasil dihapus
     */
    public int delete(Iterable<Integer> ids) {
        int count = 0;

        for (Integer Id : ids) {
            repository.delete(Id);
            count++;
        }
        logger.info("{} records of Department entity have been deleted.", count);

        return count;
    }

    /**
     * Menampilkan data informasi Department.
     *
     * @param id Department identity
     * @return Record department
     */
    public Department find(Integer id) {
        logger.info("Find Department entity with ID: {}.", id);
        return repository.findOne(id);
    }

    /**
     * Menampilkan daftar Department.
     *
     * @param pageable Paging and sorting method
     * @return The slice collection or data-paging collection of Department entity.
     */
    @Transactional(readOnly = true)
    public Page<Department> listAll(Pageable pageable) {
        logger.info("Display list of Department entity.");
        return repository.listAllWithStats(pageable);
    }

    public void update(Department entity) throws EntityNotFoundException {
        if (entity == null || entity.getDeptId() == null) {
            throw new EntityNotFoundException("entity.department.NotFound");
        }
        Department record = repository.findOne(entity.getDeptId());
        if (record == null) {
            throw new EntityNotFoundException("entity.department.NotFound");
        }

        repository.save(entity);
        logger.info("Updating department: {}", entity);
    }
}

Selanjutnya pada Project Explorer pilih package org.fajarapps.jpacrud.domain dan melalui popup menuitem buat class baru yakni: PersonModel. Ketik source code berikut untuk PersonModel.java.

package org.fajarapps.jpacrud.domain;

/* import ... tidak ditampilkan */

@Repository
@Transactional(readOnly = false)
public class PersonModel
{
    private final Logger logger = LogManager.getLogger(getClass());
    @Autowired
    private IPersonRepository repository;
    @Autowired
    private IDepartmentRepository departmentRepository;

    /**
     * Menambahkan record personil baru.
     *
     * @param entity Data personil
     */
    public void create(Person entity) {
        Person result = repository.save(entity);
        logger.info("Creating Person entity with data: {}", result);
    }

    /**
     * Menghapus record personil dari database.
     *
     * @param personId Personil identity
     * @throws EntityNotFoundException
     */
    public void delete(Long personId) throws EntityNotFoundException {
        Person person = repository.findOne(personId);
        if (person == null) {
            throw new EntityNotFoundException("entity.person.NotFound");
        }

        repository.delete(personId);
        logger.info("A Person entity have been deleted with data: {}", person);
    }

    /**
     * Menghapus beberapa record personil dari database.
     *
     * @param personIds Koleksi identity personil
     * @return Jumlah record personil yang berhasil dihapus.
     */
    public int delete(Iterable<Long> personIds) {
        int count = 0;

        for (Long personId : personIds) {
            repository.delete(personId);
            count++;
        }
        logger.info("{} records of Person entity have been deleted.", count);

        return count;
    }

    /**
     * Menampilkan data informasi personil.
     *
     * @param id Person identity
     * @return Record personil
     */
    @Transactional(readOnly = true)
    public Person find(Long id) {
        logger.info("Find Person entity with ID: {}.", id);
        return repository.findOne(id);
    }

    /**
     * Menampilkan daftar personil berdasarkan kriteria filter tertentu.
     *
     * @param deptId   Department identity
     * @param term     Kriteria pencarian berdasarkan nama lengkap personil
     * @param pageable Paging and sorting method
     * @return The slice collection or data-paging collection of Person entity.
     */
    @Transactional(readOnly = true)
    public Page<Person> findAllByCriteria(Integer deptId, String term, Pageable pageable) {
        logger.info("Display list of Person entity with criteria: departement = {} and fullname = {}.", deptId, term);

        if (deptId == null && StringUtils.isBlank(term)) {
            return repository.findAll(pageable);
        }
        else if (deptId != null && StringUtils.isNotBlank(term)) {
            Department dept = departmentRepository.findOne(deptId);
            return repository.findByDepartementAndTerm(dept, "%" + term + "%", pageable);
        }
        else if (deptId != null && StringUtils.isBlank(term)) {
            Department dept = departmentRepository.findOne(deptId);
            return repository.findByDepartement(dept, pageable);
        }
        else {
            return repository.findByTerm("%" + term + "%", pageable);
        }
    }

    /**
     * Menampilkan daftar personil.
     *
     * @param pageable Paging and sorting method
     * @return The slice collection or data-paging collection of Person entity.
     */
    @Transactional(readOnly = true)
    public Page<Person> listAll(Pageable pageable) {
        logger.info("Display list of Person entity.");
        return repository.findAll(pageable);
    }

    /**
     * Memperbarui record personil.
     *
     * @param entity Record personil yang telah diperbarui
     * @throws EntityNotFoundException
     */
    public void update(Person entity) throws EntityNotFoundException {
        if (entity == null || entity.getPersonId() == null) {
            throw new EntityNotFoundException("entity.person.NotFound");
        }

        Person record = repository.findOne(entity.getPersonId());
        if (record == null) {
            throw new EntityNotFoundException("entity.person.NotFound");
        }

        updateFields(entity, record);
        repository.save(record);
        logger.info("Updating person: {}", entity);
    }

    /**
     * Update persistence entity with transient entity.
     *
     * @param source transient entity
     * @param target persistence entity
     */
    private void updateFields(Person source, Person target) {
        target.setDepartment(source.getDepartment());
        target.setFullname(source.getFullname());
        target.setAddress(source.getAddress());
        target.setProvince(source.getProvince());
        target.setEmail(source.getEmail());
        target.setBirthDate(source.getBirthDate());
        target.setBirthPlace(source.getBirthPlace());
        target.setHomePhone(source.getHomePhone());
        target.setMobilePhone(source.getMobilePhone());
        target.setWorkPhone(source.getWorkPhone());
        target.setGender(source.getGender());
    }
}