【问题标题】:Mapping Custom Named/Native Queries to Entities将自定义命名/本机查询映射到实体
【发布时间】:2014-08-26 21:53:23
【问题描述】:

是否可以将自定义本机/命名查询映射到实体?我有这样的东西

NamedQueries({
    NamedQuery(name = "StateBo.findByCountry", query = "SELECT state FROM StateBo state WHERE state.country.id = ?"),
    NamedQuery(name = "StateBo.showIdfindByCountry", query = "SELECT state.id FROM StateBo state WHERE state.country.id = ?")
})
@Table(name = "STATE")
@Entity(name = "StateBo")
public class StateBo extends BaseNamedBo {

    private static final long serialVersionUID = 3687061742742506831L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "STATE_ID")
    private Long id;

    @Column(name = "ISO_CODE")
    private String isoCode;

    @ManyToOne
    @JoinColumn(name = "COUNTRY_ID")
    private CountryBo country;

   // getters and setters ...
}

我有我的方法可以像这样调用本机/命名查询。

@Override
public List<E> executeQuery(String queryName, List<Object> criteria) {
TypedQuery<E> query = entityManager.createNamedQuery(queryName, entityClass);
Integer argumentPosition = 1;
if ( (criteria != null) && (criteria.size() > 0) ){
  for(Object object : criteria) {
    query.setParameter(argumentPosition, object);
    argumentPosition++;
  }
}
return (List<E>) query.getResultList();
}

当我调用 StateBo.findByCountry 时,结果会映射到 StateBo,但如果我调用 StateBo.showIdfindByCountry,结果不会被映射到 StateBo 因为我只在查询中选择了 state.id 而不是表上的字段。

我不想选择 STATE 表的所有字段,在这种情况下我只想要 state.id,但是当我自定义我的原生查询时, 结果不是映射到 StateBo 而不是 this,结果是 Long 类型。

我的问题是,StateBo.showIdfindByCountry 的结果是否可能映射到实体?如果我有更多字段,例如 state.isoCode,是否可以映射到 StateBo,自定义查询?或者只有在我返回查询中的所有字段时才有可能,例如第一个查询 StateBo.findByCountry

【问题讨论】:

  • 不要考虑这样做。您和您的同事将受到这样的设计决策的影响。如果方法返回 StateBo 实例,则调用者期望获得实际的附加 StateBo 实例。未分离 StateBo 实例,其中所有字段均为空且所有不变量均已损坏,因为它仅包含一个 ID。返回 ID 的方法应返回 List&lt;Long&gt;。返回 ID/代码对的方法应返回 List&lt;StateIdAndCode&gt;。请注意,返回实体的 3 个字段中的 2 个不会比返回实体本身带来任何显着的性能优势。
  • 另外:您继续使用术语本地查询,但您的查询不是本地查询。原生查询是用 SQL 而不是 JPQL 编写的查询。
  • 谢谢,@JBNizet 我的主要疑问是,如果返回某些字段而不是所有字段,是否有助于提高性能,或者两种情况下的性能相同?
  • 请注意,返回实体的 3 个字段中的 2 个不会比返回实体本身带来任何显着的性能优势。

标签: java spring hibernate jpa eclipselink


【解决方案1】:

这是可能的,但正如 JB Nizet 所说——“你的同事会因为这样的设计决定而受苦”。

无论如何,为了做到这一点,您应该在实体类中创建自定义构造函数。此构造函数应接受 Long 参数并将其分配给您的实体类的 id 字段。

然后您应该更改您的查询以包含 NEW 关键字,后跟完整的限定实体类名称,如下所示:

SELECT NEW your.package.StateBo(sb.id)
FROM StateBo sb
WHERE state.country.id = ?

请注意,以这种方式从数据库中检索的所有实体都不会由持久性上下文管理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    • 2021-06-13
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多