使用Hibernate实现基于集合的(DDD)存储库

时间:2009-09-03 15:31:55

标签: java hibernate domain-driven-design

我正在尝试查看是否可以将存储库实现为java.util.Collection(很可能是Map)。

这些方面的东西:

@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(....) { ... }
}

我能看到的明显问题是

  • 试图避免对数据库提出非常愚蠢的请求
  • 同步化

在我的域模型中,有很多时候将DB视为List / Map / Set是有用的,所以尝试使用标准java.util接口实现这一点似乎是明智的。

那里有这样的例子吗?我是否会试图做一些事情,比如通过Hibernate将Comparable.compareTo操作推送到数据库?

1 个答案:

答案 0 :(得分:1)

在hibernate中,存储库的粗略等价物是DAO。您可以查看该模式以及它们如何在该链接上实现它;你可能会把它变成类似于存储库的东西。

在许多n层体系结构中,事务语义在与DAO不同的层上处理。因此,您可能需要重新考虑该部分,或者找到将它们集成到存储库中的方法。

为了避免不必要或重复的交互,您可以考虑使用二级缓存。