Entity単位のServiceに共通の親クラスを持たせる

どうにかして型パラメータからAbstractServiceのclazzへセットしたかったのですが、やり方わからず。。。

ジェネリックの部分があまりスマートなやり方じゃない気がしていますが、ひとまず以下のやり方だとOKです。


まずはジェネリックな共通親サービスクラスです。

public abstract class AbstractService<E> {
    // JDBCマネージャー
    public JdbcManager jdbcManager;

    // Entityのクラス
    protected Class<E> clazz;
    
    @SuppressWarnings("unchecked")
    public AbstractService() { 
        Type type = this.getClass().getSuperclass().getGenericSuperclass();
        Type[] arrays = GenericUtil.getGenericParameter(type);
        clazz = (Class<E>)GenericUtil.getRawClass(arrays[0]);    
    }

    @SuppressWarnings("unchecked")
    public E find(Integer id) {
        return (E) jdbcManager.from(clazz).id(id).getSingleResult();
    }
    
    @SuppressWarnings("unchecked")
    public List<E> findAll() {
        return (List<E>) jdbcManager.from(clazz).getResultList();
    }

    public int delete(Integer id) {
        E entity = (E)find(id);
        if (entity == null) {
            return 0;
        }
        return jdbcManager.delete(entity).execute();
    }

    ...

}

ポイントは、コンストラクタ内で AbstractService における E のクラス型を取得して clazzへセットしている箇所です。


次にエンティティ単位のサービスクラスです。

public class EmployeeService extends AbstractService<Employee>{
   /**
    * ここに個別のメソッドを定義
    */

}

EmployeeエンティティをAbstractServiceのジェネリックパラメータに指定しているだけのスッキリした構成です。


サービスを呼び出し側のコードはこんな感じです。

@Resource
protected EmployeeService employeeService;

・・・

List<Employee> list = employeeService.findAll();

Employee employee= employeeService.find(1);

int result = employeeService.delete(1);


SAStruts + S2JDBCで『Serviceの粒度 = Entity単位』で実装する場合は、このやり方だとかなり良い感じですね。