在Hibernate / JPA中查询基类对象时出现“太多表”错误

时间:2013-09-08 16:02:53

标签: hibernate jpa

我的班级模型是以下列方式。 有一个名为“IdClass”的Base类,它有id,version,createdBy,createdDate等信息。 所有其他实体类派生自此基类(因此自动获取id,版本等IdClass属性)。

我使用Hibernate / JPA来处理这些类的数据库级实现。

我添加了另一个名为Attachment的类,其中包含一个用于存储任何附件的blob。为了保持通用性,我在附件中添加了对IdClass的引用。这样,任何实体都可以拥有一个或多个附件,而不必在每个表中存储blob。

问题是当我尝试插入Attachment对象时。我需要添加对指定实体的引用。我有一个公共服务方法“createAttachment”,它接受一个附件对象和实体的“id”。现在,在这个方法中,我需要使用这个'id'找到实体,然后将它与新的Attachment对象相关联。为此,我编写了以下方法“findEntity”

public IdClass findEntity(Long id) {

    IdClass entity;
    entity = (IdClass) getSession().get(IdCass.class, id);
    return entity;
}

但是当这个方法被执行时,我得到一个异常,说“太多表:MySQL只能在一个连接中使用61个表”。 我有超过100个实体。休眠/ JPA。看起来Hibernate / JPA试图在IdClass的所有子类上进行连接,只需查询IdClass表本身就足够了(因为id存储在IdClass表中)。

另外,我尝试创建Hibernate Criteria查询来搜索实体。即使这会导致相同的表太多错误。

请让我知道我做错了什么。如何仅使用id获取IdClass对象(不必在所有子类表上引入连接)?

1 个答案:

答案 0 :(得分:0)

这不是最简洁的解决方案,但我能够使用NamedQuery解决同一问题:

@NamedQuery(name="BaseItem.findById", 
            query="SELECT a FROM BaseItem a WHERE a.id = :id")

然后我有以下实用程序函数来调用查询(使用纯JPA):

    @SuppressWarnings("unchecked")
    public static <T extends BaseItem> T findById(Class<T> entityClass, long id, 
                                                  EntityManager em) {
        try {
            Query query = em.createNamedQuery("BaseItem.findById");
            query.setParameter("id", id);

            T result = (T)query.getSingleResult();
            return result;
        }
        catch (NoResultException ignored) {
            //expected
        }
        catch (Exception e) {
            LOG.warn("Failed to execute 'findByAndId' query for id=" + id, e);
        }

        //couldn't find it
        return null;
    }

使用它通过id通过超类查找任意实体,我调用:

BaseItemDAO.findById(BaseItem.class, id, em);

然后JPA / Hibernate在幕后发挥其魔力,确保返回的内容是提供的id的完整子类实体,而不仅仅是超类字段。并且它没有因“太多表”错误而死亡。