Одиночные DAO и общие методы CRUD (JPA/Hibernate + Spring)

Следуя моему предыдущему вопросу, DAO и сервисные уровни (JPA/Hibernate + Spring), я решил использовать только один DAO для моего уровня данных (на наименее в начале) в приложении с использованием JPA/Hibernate, Spring и Wicket. Было предложено использование общих методов CRUD, но я не очень уверен, как реализовать это с помощью JPA. Не могли бы вы привести мне пример или поделиться ссылкой?

Ответ 1

Вот пример интерфейса:

public interface GenericDao<T, PK extends Serializable> {
    T create(T t);
    T read(PK id);
    T update(T t);
    void delete(T t);
}

И реализация:

public class GenericDaoJpaImpl<T, PK extends Serializable> 
    implements GenericDao<T, PK> {

    protected Class<T> entityClass;

    @PersistenceContext
    protected EntityManager entityManager;

    public GenericDaoJpaImpl() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass()
             .getGenericSuperclass();
        this.entityClass = (Class<T>) genericSuperclass
             .getActualTypeArguments()[0];
    }

    @Override
    public T create(T t) {
        this.entityManager.persist(t);
        return t;
    }

    @Override
    public T read(PK id) {
        return this.entityManager.find(entityClass, id);
    }

    @Override
    public T update(T t) {
        return this.entityManager.merge(t);
    }

    @Override
    public void delete(T t) {
        t = this.entityManager.merge(t);
        this.entityManager.remove(t);
    }
}

Ответ 2

Основываясь на статье Не повторяйте DAO, мы использовали этот вид техники в течение многих лет. Мы всегда боролись с проблемами с нашими образцами после того, как поняли, что совершили большую ошибку.

С помощью инструмента ORM, такого как Hibernate или JPA, вам не придется рассматривать DAO и Service layer отдельно. Вы можете использовать EntityManager из ваших классов обслуживания, поскольку вы знаете жизненный цикл транзакций и логику своих классов объектов.

Вы сохраняете любую минуту, если вы вызываете myDao.saveEntity вместо просто entityManager.saveEntity? Нет. У вас будет ненужный класс dao, который ничего не сделает, но будет оберткой вокруг EntityManager. Не бойтесь писать выборки в своих классах обслуживания с помощью EntityManager (или сеанса в спящем режиме).

Еще одно примечание: вы должны определить границы своего уровня обслуживания и не позволить программистам возвращать или ждать классы Entity. Программисты уровня UI или WS не должны вообще знать об классах сущностей только о DTO-s. Объекты Entity имеют жизненные циклы, о которых большинство программистов не знают. У вас возникнут серьезные проблемы, если вы сохраните объект сущности в данных сеанса и попробуйте обновить его до базы данных через несколько секунд или несколько часов. Ну, вы можете этого не делать, но программист пользовательского интерфейса, который знает типы параметров и возвращаемые типы вашего уровня обслуживания, только сделал бы, чтобы сохранить некоторые строки кода.

Ответ 3

Я искал одно и то же. Я нашел то, что похоже на это, - проект Spring-Data JPA, предоставленный SpringSource. Это порт кода из Hades и теперь (начало 2011 года) проглочен Spring и лучше интегрирован. Он позволяет использовать один dao (SimpleJpaRepository) со статическим созданием или расширять базовый класс JpaRepository для создания любого конкретного объекта dao с готовыми CRUD + методами. Кроме того, позволяет использовать запросы типа grails, используя имена параметров как имя метода - в интерфейсе (не требуется реализация!), Т. Е. findByLastname(String lastName); Выглядит очень многообещающе - участие в проектах Spring, безусловно, обеспечит будущее. Я начал реализовывать это в своем предстоящем проекте сейчас.

Ответ 4

Если вы ищете стороннюю реализацию, вы можете проверить http://www.altuure.com/projects/yagdao/. это основанная на nnotation общая инфраструктура DAO, которая поддерживает JPA и hibernate