如何在Hibernate中选择索引列?

时间:2015-12-14 13:59:05

标签: java hibernate

我有一个数据库表与typevalue通信,外键作为索引,映射回一个声明如下的Person表:

@Table(name = 'communication', schema = 'schema')
  @org.hibernate.annotations.Table(appliesTo = 'communication', indexes = {
    @Index(name = "idx_communication_person_id", columnNames = { "person_id" })
  }
)

Person对象映射为:

@OneToMany(fetch = LAZY, cascade = ALL, orphanRemoval = true)
@JoinColumn(name = "person_id")
@OrderColumn
@Index(name = "idx_communication_person_id")
private final List<Communication>       communications

现在我想用Hibernate创建一个HQL查询,它根据这个索引列选择,如:

WHERE person.id in ( SELECT c.person_id FROM Communication c WHERE c.type = 3 AND c.value = 'john.doe@server.com' )

这不起作用,因为此时HQL并不知道c.person_id,因为HQL通常不知道索引列。

如何在HQL中正确地处理索引,或者如果不可能:如何编写语句以与上面的本机查询相同地进行存档?

编辑:出于性能原因,不得以任何形式加入。

2 个答案:

答案 0 :(得分:0)

  

这不起作用,因为此时HQL不知道c.person_id,因为HQL通常不知道索引列。

这对我来说没什么意义。

如果您希望有一个HQL语句根据某些条件返回Person的标识符列表,您可以像编写SQL语句一样轻松地执行此操作。

SELECT p.id
  FROM Communication c JOIN FETCH c.person p
 WHERE c.type = :communicationType
   AND c.value = :emailAddress

如果您真的想要人,只需编写查询以选择c.person而不是p.id,以便为所有人提供保湿。在下文中,查询允许您在谓词上指定人员标识符(如果需要)。

SELECT c.person
  FROM Communication c JOIN FETCH c.person p
 WHERE c.person.id = :personId
   AND c.type = :communicationType
   AND c.value = :emailAddress

<强>更新

如果您不想使用任何联接,那么只需将personId公开为Communication实体上的数值,而不进行任何关联映射。

public class Communication {
  @Column(name = "personId", nullable = false, insertable = false, updatable = false)
  private Long personId;
}

然后,您应该能够发出如下查询:

SELECT c.personId
  FROM Communcation c
 WHERE c.type = :communicationType
   AND c.value = :emailAddress

答案 1 :(得分:0)

我认为你需要这样的东西:

SELECT p.* FROM person p 
    JOIN p.communication c
WHERE c.type = 3 AND c.value = 'john.doe@server.com'