如何使用Hibernate Annotations在Lob / Clob / tinyblob上添加索引

时间:2009-05-13 14:36:43

标签: java mysql hibernate

我有一个bean,我使用Hibernate映射到数据库。我正在使用Hibernate Annotations来指示我想要的映射,并创建索引。完全简化的代码如下所示。

我遇到的问题是我的byte []字段上的索引没有创建;特别是我的多字段索引sysUuid没有被创建(参见示例代码)。在Hibernate调试日志中,我甚至没有看到创建索引的尝试!

我想指出uuid字段上的@Index注释也不会导致数据库上的索引。

我知道如何使用MySQL手动创建索引:

create index sysuuid on persons ( system, `uuid`(8) );

其中有趣的特性是uuid需要被转义(因为它是一个MySQL函数)并且需要在字段上给出长度(与文本字段一样)。

但是我还没有找到一种方法来使用Hibernate Annotations给出索引长度字段,所以我无法测试是否存在问题。但是,确定在注释中命名字段“uuid(8)”不起作用。

@Entity
// The UniqueConstraints work 
@Table(name = "persons", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"uid", "system"}) } )
// but these don't generate an index
@org.hibernate.annotations.Table(appliesTo="persons", 
   indexes={@Index(name="sysUuid",  columnNames={"system", "uuid"})  } )
public class Person  {
    @Basic 
    @NotNull
    private String uid;

    @Basic
    private int system;

    // Gets mapped to tinyblob
    @Basic
    @Size(min = 16, max = 16)
    private byte[] uuid;

    // getters and setters here 
}

我想问你的是:是否可以使用注释在lob上添加索引,若然,怎么做?

修改

我确实可以转移到基于字符串的UUID,但我对此并不熟悉,因为uuid在概念上是一个16字节的标识符。

我强烈希望Java类型与问题域匹配。

正如我所说 - 我有一个方便的SQL语句,所以我可以部署代码+一个SQL脚本。我认为最好在可行的情况下使用自我记录代码。

编辑&添加了Bounty

我相信我需要的索引不能使用Hibernate Annotations创建(重新.Mat Solnit的回答)。

但是,我会更多地了解有关使用Hibernate Annotations创建索引的更多信息,因此最终的答案最终会记录其中的局限性。 API。

3 个答案:

答案 0 :(得分:3)

您可以使用Hibernate的auxiliary objects支持来完成此操作,但无法使用注释完成此操作: - (。

在你的例子中,它看起来像这样(为了简洁省略了许多东西):

<class name="Person" table="persons">
  <!-- whatever -->
  <database-object>
    <create>create index sysuuid on persons ( system, `uuid`(8) )</create>
    <drop>drop index sysuuid</drop>
    <dialect-scope name="org.hibernate.dialect.MySQL5InnoDBDialect" />
  </database-object>
</class>

我为缺乏基于注释的答案道歉:-(。希望这会有所帮助。

注意:如果采用此方法,请注意方言范围必须与完全匹配。例如,如果您的Hibernate配置说使用MySQL5InnoDBDialect,那么您必须在<dialect-scope>元素中使用此方言。即使它是InnoDB方言的超类,使用MySQLDialect也行不通。

答案 1 :(得分:1)

您真正想要做的是将UUID属性定义为String而不是字节数组。这样Hibernate会将它映射到数据库中的字符列而不是LOB,我认为它会创建你想要的索引。

答案 2 :(得分:0)

以下是我对MySQL的研究结果。如果你有一个长度很大的领域:

@Column(length = 2000)
public String getMessageId() {
    return messageId;
}

然后它的类型将是BLOB并且索引不起作用:

HHH000389: Unsuccessful: create index messageid_idx on MessageDetails (messageId)
BLOB/TEXT column 'messageId' used in key specification without a key length      

如果使用注释,添加自定义sql的唯一方法如下:

    cfg.addAuxiliaryDatabaseObject(new SimpleAuxiliaryDatabaseObject(
            "CREATE INDEX messageId_IDX ON MessageDetails(MessageID(128))",
            "DROP INDEX messageId_IDX ON MessageDetails"));

其中cfg是用于注册注释的对象:

    cfg.addAnnotatedClass(MessageDetails.class);
这对我有用。 Thanx引起你的注意。