Some of posts from this blog has been moved to dywicki.pl. You will be automatically redirected to new blog if you would submit comment.
New posts are published on dywicki.pl, this blog contains old content related to Code-House company.


Niektóre posty z tego bloga zostały przeniesione do dywicki.pl. Zostaniesz automatycznie przekierowany jeśli bedzięsz chciał dodać komentarz.
Nowe posty sa publikowane na dywicki.pl, ten blog zawiera stare treści związane z firmą Code-House.

Dwie klasy redukujące ilość kodu w encjach JPA

Z pewnością nie jest to odkrycie godne podziwu czy też coś, co może realizować z nowinkami JPA 2.0, nie mniej jest to kod bez którego żaden projekt obejść się nie może – mianowicie identyfikacja encji.

Borykałem się z problemem dosyć pospolitym, mianowicie pozbyciem się z każdej encji kodu:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

Nic dziwnego, 40 encji to aż 120 powtórzonych, niepotrzebnie powielonych linii. Nie są obce mi wzorce dziedziczenia, które Martin Fowler opisywał w swojej książce, w tym przypadku chodzi o dziedziczenie mapowanych pól a nie fizyczne odwzorowanie tej hierarchii, czyli zagrywka czysto techniczna.

Odpowiedni kod znalazłem w przykładowej aplikacji z dystrybucji Spring Framework 3. Jedyny szkopuł to że całość spisana w XML. W mapowaniu jest jednak rozwiązanie zagadki – mianowicie element mapped-superclass. Po nitce do kłębka – trafiłem na adnotację @MappedSuperclass. Kilka linii które uprościły mój kod to:

// Copyright (C) 2009 Code-House
// All rights reserved
package org.code_house.domain;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

/**
 * Klasa bazowa dla encji.
 * 
 * @author Łukasz Dywicki luke@code-house.org
 */
@MappedSuperclass
public class BaseEntity {

    /**
     * Identyfikator encji.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * Pobranie wartości pola id.
     * 
     * @return Wartość id.
     */
    public Long getId() {
        return id;
    }

    /**
     * Ustawienie wartości pola id.
     * 
     * @param id Nowa wartość pola id.
     */
    public void setId(Long id) {
        this.id = id;
    }
}

Drugi przypadek to encja nazwana, czyli coś co ma nazwę. Może to być encja reprezentująca klienta bądź firmę. Cokolwiek, co można nazwać. Ot, chociażby samochód (dla przykładu na swoje seicento zwykłem mówić ciężarówka), ilość takich przypadków można naturalnie mnożyć, ale nie o to nam chodzi.

// Copyright (C) 2009 Code-House
// All rights reserved
package org.code_house.domain;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;

/**
 * Encja zawierająca pole z nazwą.
 *
 * @author Łukasz Dywicki luke@code-house.org
 */
@MappedSuperclass
public class NamedEntity extends BaseEntity {

    /**
     * Nazwa przypisana do encji.
     */
    @Column
    private String name;

    /**
     * Pobranie wartości pola name.
     *
     * @return Wartość name.
     */
    public String getName() {
        return name;
    }

    /**
     * Ustawienie wartości pola name.
     *
     * @param name Nowa wartość pola name.
     */
    public void setName(String name) {
        this.name = name;
    }

}

Zamierzony efekt osiągnięty – definicje encji krótsze, kod sprzątnięty. Całość projektu, razem z dokumentacją i tym podobnymi jest dostępna w repozytorium Code-House.

 

One trackback

Leave a reply