当前位置: 首页 > 知识库问答 >
问题:

Hibernate返回基类的代理

萧晔
2023-03-14

我的域模型中有一个层次结构,由类描述:

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class BaseEntity {
    @Id
    private Long id;

    // other fields
}

@DiscriminatorValue(value = "Individual")
public class IndividualEntity extends BaseEntity {
    // fields
}

@DiscriminatorValue(value = "Branch")
public class BranchEntity extends BaseEntity {
    // fields
}

我正在获取如下对象:

Specification<BaseEntity> specification = createSpecification();
BaseEntity entity = baseRepository.findOne(specification);

(我使用的是spring数据

问题是Hibernate返回代理对象(据我所知),但代理属于BaseEntity,而不是正确的子类(其“类是BaseEntity\u$$\ uJVSTED9\u26,因此IndividualEntity的实体实例为false)。

有趣的是,并非所有对象都作为代理返回。
我在循环中获取实体(公共事务),其中一些以正常形式返回(即个性化实体/分支实体),一些作为代理。
如果我改变机制,那么每个获取都在单独的事务中完成-根本不返回代理对象。

我知道我可以打开该代理(如此处),但这种行为的原因是什么(对我来说有点奇怪),我可以避免吗?

共有1个答案

鲍建业
2023-03-14

如果没有看到更多的对象模型,就无法确定,但Hibernate会这样做的一个原因是,如果BaseEntity已经被解析为同一个BaseEntity的代理。会话中较早的id。

例如,如果有另一个类与基本实体(BaseEntity)有ToOne关系,那么它将只具有id的外键,因此将使用基本实体(BaseEntity)$$ 代理延迟解析另一端的正确子类。然后,这将成为在Hibernate PersistenceContext中管理的id的实例。

显然是Hibernate。unwrap(),或上面链接中的其他选项之一将显示“true”实例。另一种选择是在基本实体上使用抽象方法(例如,isIndividual())。这看起来有点整洁,但最终Hibernate仍需要在调用该方法时解析代理。

 类似资料:
  • 假设我已经包装了我的C类和,并且可以通过SWIG生成的模块从Python访问它们: 在Python中,我创建了面向用户的类,它是一个浅层代理,主要添加docstring,并允许IDE对参数名称进行制表符补全: 问题在于,返回类型为,它没有docstring,也不显示参数名称(swig将所有参数公开为)。相反,我希望它提供我自己的浅代理

  • 问题内容: 我有一个服务方法,该服务方法调用DAO,然后从数据库中返回一个对象。从系统的许多部分调用此方法。但是,一种特定的方法是将ObjectClass _ $$ _ javassist_somenumber的返回类型作为该类型。这是丢东西。我将service方法称为与其他任何地方完全相同的方法,那么为什么hibernate会返回代理而不是自然对象? 我知道有很多方法可以暴露“代理”对象,但是我

  • 假设我有一个应用程序,有许多不同的实体,它们之间没有关系。 我想创建一个搜索,查询所有这些,但返回一个统一的类型,即: 你认为有办法让它起作用吗?

  • 下面的代码来自一个名为ButterKnife的Android库。我正在弄清楚它是怎么工作的。 我试图重新创建此函数的行为: 和用法: 但是异常并非永远不会被捕获,而是在调用方法时在行中抛出。为什么? 还有,这到底是如何工作的?该方法如何知道要转换到什么?

  • 我试着写一个小函数,它接受两个列表,并根据另一个列表的元素对一个进行排序。所以类似于: 将产生一个排序列表。 然而,可能是一个不同的列表,比如整数、浮点数或其他列表。理想情况下,我希望我的程序能够获取我抛出的任何列表,根据

  • 我有一个mysql查询,它连接5个不同的表以返回产品的特定属性。它应该只返回每个产品一次。但是由于产品可能有多个类别,它为每个类别返回产品一次。 以下是选择: 如果给定的产品,比如product_id32被分配到多个类别,它将为每个类别返回一次product_id32,唯一的区别是结果是类别名称。 如果有人可以帮助返工选择只包括每个产品一次,无论类别我将不胜感激的帮助。 将类别恢复为产品的MAX(