使用Hibernate获取通用对象

时间:2012-02-28 09:56:25

标签: java hibernate generics

我正在尝试使用hibernate来构建我从源网站获取的本地数据缓存。我有使用JPA配置的对象(如果它有所不同)并且可以在测试应用程序中读/写它们。

现在我想将代码移动到通用的“缓存”类中,以便我可以从缓存中请求一个对象并正常处理它。我可以从数据库中读取对象并将其传递回调用类,但是当我尝试访问对象中的集合时,我得到了可怕的延迟初始化异常。 我知道是什么导致了这个,我读取对象的类在从数据库读取对象之后以及在将对象返回给调用类之前提交事务。

我已经尝试了各种方法来解决这个问题,最简单的(对我而言)似乎是尝试访问对象中的所有集合,以确保在关闭事务和返回对象之前加载它们。

这种方法的问题是我不知道我从数据库中检索的对象的结构(对我来说是Hibernate的一部分好处),因此我无法调用适当的方法来加载数据。我该如何克服这个问题?我真的不想急于提取对象,因为它们可能被其他应用程序使用。如果可以避免,我不想使用hbm文件。

这是对Cache类的调用:

Series series = (Series) Cache.getFromCache(id, Series.class)

在Cache类中:

public static Object getFromCache(String key, Class clazz) {
Object dbObject = HibernateUtil.loadObject(clazz, key);

    if (dbObject != null) {
        logger.debug("Cache (Get): Got object (" + clazz.getSimpleName() + ") for " + key);
        return dbObject;
    }
}

HibernateUtil确实:

public static Object loadObject(Class clazz, Serializable key) {
    Session session = sessionFactory.getCurrentSession();
    Object dbObject;

    try {
        session.beginTransaction();
        dbObject = clazz.cast(session.get(clazz, key));
    } finally {
        session.getTransaction().commit();
    }

    return dbObject;

1 个答案:

答案 0 :(得分:1)

首先,您可以通过参数化loadObject方法来避免类型转换:

public static <T> T loadObject(Class<T> clazz, Serializable key) {
    Session session = sessionFactory.getCurrentSession();
    T dbObject;

    try {
        session.beginTransaction();
        dbObject = clazz.cast(session.get(clazz, key));
    } 
    finally {
        session.getTransaction().commit();
    }

    return dbObject;
}

第二:为什么要在这种方法中打开并提交交易?让调用者打开一个事务并在他完成使用从缓存加载的对象时提交它将解决问题。

第三:如果你真的想让这个方法打开并关闭事务,那么让它以Initializer<T>实例作为参数。这个初始化程序有责任在返回实体之前初始化所有必要的关联。

public static <T> T loadObject(Class<T> clazz, 
                               Serializable key, 
                               Initializer<T> initializer) {
    Session session = sessionFactory.getCurrentSession();
    T dbObject;

    try {
        session.beginTransaction();
        dbObject = clazz.cast(session.get(clazz, key));
        initializer.initialize(dbObject);
    } 
    finally {
        session.getTransaction().commit();
    }

    return dbObject;
}