views:

487

answers:

1

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

  • trying to avoid really silly requests to the DB
  • syncronization

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?

+1  A: 

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.

eqbridges
Yeah, I'm familiar with the DAO pattern, I just want to see if it is possible to expose a java.util.Collection Repository. Transactions would be demarked at the service layer, the code above was just the result of me playing. Still hoping someone can point me to some code or article exploring this idea.
ptomli