ptomli
ptomli

Reputation: 11818

Implementing Collections based (DDD) Repository with Hibernate

I'm trying to see if it's possible to implement a repository as a java.util.Collection (most likely a Map).

Something along these lines:

@Repository
public abstract class HibernateRepository<K extends Serializable, V>
    extends AbstractMap<K, V> {

    @Autowired
    private SessionFactory sessionFactory;

    private Class<K> keyClass;
    private Class<V> valueClass;

    public HibernateRepository(Class<K> keyClass, Class<V> valueClass) {
        this.keyClass = keyClass;
        this.valueClass = valueClass;
    }

    @Override
    @SuppressWarnings("unchecked")
    public V get(Object key) {
        return (V) sessionFactory.getCurrentSession()
                                 .get(valueClass, (Serializable) key);
    }

    @Override
    @Transactional
    public Set<java.util.Map.Entry<K, V>> entrySet() {
        return new EntrySet(sessionFactory.getCurrentSession());
    }

    private class EntrySet extends AbstractSet<java.util.Map.Entry<K, V>> {

        private Session session;

        public EntrySet(Session session) {
            this.session = session;
        }

        @Override
        public Iterator<java.util.Map.Entry<K, V>> iterator() {
            // Hibernate Criteria doesn't do Iterator
            // so would probably a fair bit of manual work
            // if multiple DB requests are to be avoided
        }
        @Override
        public int size() {
            return (Integer) session.createCriteria(valueClass)
                                    .setProjection(Projections.rowCount())
                                    .uniqueResult();
        }
    }
}

public class FooRepository extends HibernateRepository<Integer, Foo> {
    public FooRepository() { super(Integer.class, Foo.class); }

    // domain specific queries/methods...
    public Foo findMagicOne(....) { ... }
}

Obvious issues I can see are

In my domain model there are plenty of times it would be useful to treat the DB as List/Map/Set, so trying to achieve this using the standard java.util interfaces seems sensible.

Are there examples of this out there? Am I going to fall on my face trying to do things like pushing Comparable.compareTo operations down to the DB via Hibernate?

Upvotes: 1

Views: 2336

Answers (1)

Edward Q. Bridges
Edward Q. Bridges

Reputation: 18310

In hibernate, the rough equivalent of a repository is the DAO. You might take a look at that pattern and how they implement it at that link; you could probably evolve that into something like a repository.

In many n-tier architectures, the transactional semantics are handled at a different tier than the DAO. So you may want to reconsider that part, or find a way to integrate them into the repository.

In order to avoid unnecessary or duplicate interactions you may consider using a second-level cache.

Upvotes: 1

Related Questions