【问题标题】:How to define index by several columns in hibernate entity?如何通过休眠实体中的几列定义索引?
【发布时间】:2010-02-02 09:26:49
【问题描述】:

早上。

我需要在休眠实体中添加索引。据我所知,可以使用@Index 注释为单独的列指定索引,但我需要为实体的多个字段创建索引。

我在谷歌上搜索并找到了 jboss 注释 @Table,它允许这样做(按规范)。但是(我不知道为什么)这个功能不起作用。可能是 jboss 版本低于必要的版本,或者我不明白如何使用这个注释,但是......没有创建复杂的索引。

为什么不能创建索引?

jboss 版本 4.2.3.GA

实体示例:

package somepackage;
import org.hibernate.annotations.Index;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
@org.hibernate.annotations.Table(appliesTo = House.TABLE_NAME,
    indexes = {
            @Index(name = "IDX_XDN_DFN",
                    columnNames = {House.XDN, House.DFN}
            )
    }
)

public class House {
    public final static String TABLE_NAME = "house";
    public final static String XDN = "xdn";
    public final static String DFN = "dfn";

    @Id
    @GeneratedValue
    private long Id;

    @Column(name = XDN)
    private long xdn;

    @Column(name = DFN)
    private long dfn;

    @Column
    private String address;

    public long getId() {
        return Id;
    }

    public void setId(long id) {
        this.Id = id;
    }

    public long getXdn() {
        return xdn;
    }

    public void setXdn(long xdn) {
        this.xdn = xdn;
    }

    public long getDfn() {
        return dfn;
    }

    public void setDfn(long dfn) {
        this.dfn = dfn;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

当 jboss/hibernate 尝试创建表“house”时,它会抛出以下异常:

Reason: org.hibernate.AnnotationException: @org.hibernate.annotations.Table references an unknown table: house

【问题讨论】:

  • 顺便说一句,如果答案适合您,您应该将答案标记为已接受(选票下方的勾号)。
  • @foobar - 你的问题解决了吗?
  • 我决定使用 SQL 脚本手动创建索引。您的建议是正确的,但我认为这就像用户用作休眠方法的黑客。并且此方法不能适用于其他持久性提供程序。问题已解决,但将来我想花更多时间来了解如何以最佳方式完成此任务。我会在这里写下结果...非常感谢。
  • 查看@Pascal Thivent 的答案:它表明您的映射中缺少注释。 (来自参考文档:此注释 [@org.hibernate.annotations.Table] 应出现在 @javax.persistence.Table 出现的位置。)

标签: java hibernate orm jboss


【解决方案1】:

请尝试以下方法:

@Entity
@org.hibernate.annotations.Table(appliesTo = House.TABLE_NAME,
    indexes = {
            @Index(name = "IDX_XDN_DFN",
                    columnNames = {House.XDN, House.DFN}
            )
    }
)
@Table(name="house")
public class House {
    ...
}

请注意,这也应该允许您创建多列索引(基于索引名称):

@Index(name = "index1")
public String getFoo();

@Index(name = "index1")
public String getBar();

P.S.:顺便说一句,您使用的是什么版本的 Hibernate?什么数据库/方言?

【讨论】:

    【解决方案2】:

    您必须将 hibernate.hbm2ddl.auto 设置为在 persistence.xml 中创建。当设置为更新休眠时不会创建索引。

    hibernate.hbm2ddl.auto = create

    【讨论】:

    • 可能是jboss版本的原因
    • 一般来说好像不是这样的;对我来说,即使使用hibernate.hbm2ddl.auto=update,也会创建索引。
    【解决方案3】:

    您最好使用复合主键。

    This article 解释了如何使用 JPA 注释来做到这一点。它使用@Embeddable@EmbeddedId

    【讨论】:

    • 谢谢。使用 JPA 特定的 API 是正确的,但是......仍然不清楚为什么它在 jboss 上不起作用。我尝试使用相同的类为单独的字段指定 @Index 注释,但它也不起作用。
    • 没有必要将实体嵌入到我的业务逻辑中。必须有更简单的决定。但还不知道怎么做....是的,我读过那篇文章。
    • 这是最简单最好的解决方案。由于您的主键是复合的,因此您最好将其抽象为一个新对象。
    • Bozho,我完全同意 U,但我不想重新设计业务领域类(实体),因为它已经被应用程序使用了。
    • 注意:在 Oracle 中,复合主键不能包含具有空值的列,但复合唯一索引可以包含具有空值的列。因此,此答案在某些情况下没有意义(特别是当您希望允许一个或多个列包含空值并成为复合列时......)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多