Approach for a (generic) DDD Repository with JPA/Spring: does it look wrong?

二次信任 提交于 2019-12-05 02:15:11

问题


I'm pretty new to DDD and JPA.

I'm working on a generic Repository with JPA and Spring. I really like the approaches exposed in the articles DDD: The Generic Repository and JPA implementation patterns: Data Access Objects. My aim is to build the perfect Repository in Domain-Driven Design with JPA and Spring.

I use an internal generic Repository to respect the domain’s contract with the data store, following the first article concepts.

public interface IInternalGenericRepository<K, E> {
    List<E> read(String query, Object[] params);
    void persist(E entity);
    void remove(E entity);
}

public class InternalGenericRepository<K, E> implements IInternalGenericRepository<K, E> {

    // Injected through DI in Spring
    @PersistenceContext
    private EntityManager em;

    private final Class<E> entityClass;

    public List<E> read(String query, Object[] params) {
        Query q = em.createQuery(query);
        for (int i = 0; i < params.length; i++) {
            q.setParameter(i + 1, params[i]);
        }
        return q.getResultList();
    }

    public void persist(E entity) {
        em.persist(entity);
    }

    // ...
}

Then, a Repository for a particular entity (for example: Organization) looks like this.

public interface IOrganizationRepository {
    List<Organization> organizationByCityName(String city);

    void create(Organization o);
}


@Repository
public class OrganizationRepository implements IOrganizationRepository {

    @Autowired
    IInternalGenericRepository<Long, Organization> internalRepository;

    public List<Organization> organizationByCityName(String city) {
        Object[] params = new Object[1];
        params[0] = city;
        return internalRepository.read("select o from Organization o where o.city.name like ?1",
                params);
    }

    @Override
    public void create(Organization o) {
        internalRepository.persist(o);
    }
}

It looks like a good way to implement DDD Repository with JPA and Spring. The OrganizationRepository is then injected in my services layer.

I'd like to have external views to avoid flaws or misconception. What do you think and how could it be improved?

Thanks.


Edit:

  • @Autowired on internalRepository - thanks to axtavt for pointing it out.
  • read() can be improved

回答1:


First of all, it wouldn't work, because Spring can't inject EntityManager into internal object created with new. So, you have to write something like this:

public class OrganizationRepository implements IOrganizationRepository { 

    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        internalRepository.em = em;
    }
    ...
}

Also your read method looks a bit too generic. It misses some important use cases, such as getSigleResult and setFirstResult/setMaxResults.

Personally I prefer the second article apporach, because using composition you'll end up with having EntityManager in OrganizationRepository in order to implement features missed in IInternalGenericRepository.



来源:https://stackoverflow.com/questions/2239754/approach-for-a-generic-ddd-repository-with-jpa-spring-does-it-look-wrong

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!