【问题标题】:hibernate - select/load only field休眠 - 仅选择/加载字段
【发布时间】:2016-09-27 09:02:29
【问题描述】:

我想在 Hibernate 表映射/实体类中添加一个字段。

我希望此字段不映射到实际的表列,并且我希望 Hibernate 不要尝试将其插入/更新到数据库。

但我希望能够通过 DAO 中的自定义选择来加载此字段,例如通过

query.addEntity(getPersistentClass().getName());

我最接近这个的方法是创建字段@Transient
但是即使选择也不会加载其值。所以这不是
正是我需要的。

这有可能吗?如果可以,怎么做?

【问题讨论】:

  • AFAIK 瞬态是不使用 ORM 模型映射列的唯一方法。如果一个字段没有映射到数据库,那么 Hibernate 怎么可能给它赋值呢?
  • @TimBiegeleisen 我的想法是做一个 SQL 查询,例如select t.*, 1 as Disabled from table t 然后所有其他字段都来自表,我正在谈论的 Disabled 字段是从该查询返回的记录集的 Disabled 列加载的。
  • 我不确定我是否理解您的问题。该字段的价值从何而来?是在数据库中还是某个公式的结果?
  • @Thomas 好的,我刚刚在评论中举了一个例子。
  • 最符合您需要的方法是执行原始 SQL 查询。您正试图绕过 Hibernate 框架,在这种情况下,为什么不直接进行原始查询?

标签: java hibernate


【解决方案1】:

好吧,如果我了解您要做好的工作,那么我认为解决方案是这样的

@Column(name = "{name of column}", 可更新 = false)

这样,一旦对象创建,hibernate 就不会尝试更新该列

【讨论】:

  • 我知道这个updatable 的事情,但我的问题是我没有可以将此字段映射到的列。所以我根本不希望它映射到物理表列。还是谢谢。
  • 然后使用瞬态进行,如果你想从另一个表中获得这个值,你可以使用公式
  • 我不知道这是可能的。好的,我会朝那个方向做一些研究,谢谢。
【解决方案2】:

你的吸气剂必须更聪明一点。 例如,您可以像这样从 spring 中获取 HibernateCallback 接口:

public String getName(Session session) {
 return new HibernateCallback<String>() {
  @Override
  public String doInHibernate(Session session) throws HibernateException {
   return session.createSQLQuery("SELECT NAME FROM MY_TABLE WHERE SOME_CONDITIONS").uniqueResult();
  }
 }.doInHibernate(session);
}

更好的方法是在您可以访问会话的另一个类中创建一种执行方法。 使用该解决方案,您仍然可以将您的字段标记为@Transient

【讨论】:

  • 谢谢,但是如果我加载 100 个实体,那不会触发对数据库的 100 个单独查询吗?如果是这样,我不想那样。
  • 只有在被要求时才会调用数据库。但是,一天结束时是的,如果您想检索 100 个不同实体的信息,它将去数据库 100 次。也许您可以想办法用它来检索所有实体名称,只需往返一次数据库。然后将结果映射到正确的实体。
  • 是的,这就是我想知道的,如何通过 1 次往返数据库来实现。
  • 您也可以将纯 jdbc 转到数据库,以检索您之前加载的所有实体的名称和 ID。然后您可以使用 id 将结果映射到每个实体。
  • @peter.petrov 类似 'session.createSQLQuery("SELECT NAME FROM MY_TABLE WHERE SOME_CONDITIONS").addScalar("ID", Hibernate.LONG).addScalar("NAME", Hibernate.STRING) ;'这将返回一个对象数组。可以看到:docs.jboss.org/hibernate/orm/3.3/reference/en/html/…
【解决方案3】:

你可以使用 @Column(name = "{name of column}", insertable=false, updatable = false)

不要将该字段标记为@Transient。

这样这个属性不会被插入或更新,但可以在选择中使用。

【讨论】:

    猜你喜欢
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    • 2018-09-02
    • 2018-06-27
    • 2011-04-12
    • 1970-01-01
    相关资源
    最近更新 更多