休眠:创建索引

Posted

技术标签:

【中文标题】休眠:创建索引【英文标题】:Hibernate: Create Index 【发布时间】:2014-05-14 01:16:15 【问题描述】:

我想在我的数据库中创建多个索引。不幸的是,我们必须将持久性提供程序从 EclipseLink 更改为 Hibernate,但使用 javax.persistence.Index 的解决方案也无法使用 Hibernate 的解决方案。

这是类的样子:

@Entity
@Table(name = "my_shop")
public class Shop extends BaseEntity 

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Calendar lastUpdate;

这应该是 javax.persistence.* 的解决方案:

import javax.persistence.Index;
import javax.persistence.Table;

@Table(name = "my_shop",
        indexes = @Index(columnList = "lastupdate")
)

Hibernate 注释已被弃用,所以一定有理由不使用这些注释:

import org.hibernate.annotations.Index; // deprecated
import org.hibernate.annotations.Table;

@Table(...,
        indexes = @Index(columnNames = "lastupdate")
)

我使用 Glassfish 3.1.2.2、PostgreSQL 9.1、JPA 2.1 和 hibernate-core 4.3.4.Final。如果我查看数据库,没有通过 psql "\d+" 在特定字段上创建索引。

这就是我的 persistence.xml 的样子:

...
    <property name="hibernate.hbm2ddl.auto" value="create"/>
    <property name="dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
...

只有 EclipseLink 可以轻松处理:

import org.eclipse.persistence.annotations.Index;

@Entity
@Table(name = "my_shop")
public class Shop extends BaseEntity 

    @Index
    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Calendar lastUpdate;

我在@Column 和@Index 中使用“lastupdate”、“lastUpdate”和其他“name”属性的所有组合测试了给定的解决方案,但似乎没有任何效果。

更新 1

这个解决方案确实有效:

@javax.persistence.Table(name = "my_shop")
@Table(appliesTo = "my_shop"
        ,indexes = @Index(columnNames = "name", name = "name"),
                @Index(columnNames = "lastupdate", name = "lastupdate")
)

org.hibernate.annotations.Index; 仍被标记为已弃用。那么使用它是否是一种好习惯?如果不是,还有什么选择,因为显然javax.persistence.Index 不起作用。

org.hibernate.annotations.Index; 适用于每个值:创建、更新、... javax.persistence.Index 与“hibernate.hbm2ddl.auto”的哪个值无关,不起作用。

【问题讨论】:

【参考方案1】:

@Index 注释仅适用于hibernate.hbm2ddl.auto=create-drop,请参阅此entry in the Hibernate forums。

请注意,此选项会删除表格,但通常hibernate.hbm2ddl.auto 仅用于开发目的。

【讨论】:

我看到另一个官方声明:hibernate.atlassian.net/browse/HHH-1012 Request to spread index with hibernate.hbm2ddl.auto=update resolve in 3.2.x, 3.3.x, 3.5.0-Beta-2【参考方案2】:

我将 JPA 2.1 与 Hibernate 4.3 和 PostgreSQL 9.3 一起使用。我对索引没有任何问题

hibernate-commons-annotations-4.0.4.Final.jar
hibernate-core-4.3.1.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-1.1.0.Final.jar
javassist-3.18.1-GA.jar
jboss-transaction-api_1.2_spec-1.0.0.Final.jar

虽然我的配置有

<property name="hibernate.hbm2ddl.auto" value="update"/>

这就是我的实体映射

import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity
@Table(name = "users", indexes = 
        @Index(columnList = "id", name = "user_id_hidx"),
        @Index(columnList = "current_city", name = "cbplayer_current_city_hidx")
)

PS。事实上,我对这些注释有一些问题。我无法为索引指定表空间,并且必须为 SINGLE_TABLE 层次结构的父类中的子类创建索引。

【讨论】:

更新了我的答案以表明我可以使用 JPA 进行一切工作 为我工作! (只是不知道默认情况下会对唯一字段进行索引...)【参考方案3】:

总结一下:

JPA 2.1:javax.persistence.Index(参见JSR-000338,第 450 页,第 11.1.23 项) Hibernate ORM: org.hibernate.annotations.Index

【讨论】:

您的链接已损坏:jcp.org/aboutJava/communityprocess/final/jsr338/index.html【参考方案4】:

对于Hibernate,您需要在@Index 注解中输入name 属性。

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Index;
import javax.persistence.Table;

@Entity
@Table(
        indexes = 
            @Index(columnList = "description", name = "product_description")
        )
public class Product implements Serializable 
     // ...

     private String description;

     // getters and setters

EclipseLink 不是必需的,它会自动创建name

【讨论】:

【参考方案5】: JAVAX

由于 JPA 或 JERSEY 或 Spring Boot 使用 Jersey 已经包含 JAVAX 包,所以我们应该使用

 @Table(name = "userDetails", indexes=@Index(columnList="uid,name",name="Index_user"))

好处:

我们不需要添加任何额外的依赖项 我们还可以在@Table 中定义唯一键 休眠 我们可以用 @Index 做同样的事情,但为此,我们需要添加 Hibernate 依赖项。

【讨论】:

以上是关于休眠:创建索引的主要内容,如果未能解决你的问题,请参考以下文章

休眠搜索以处理两个不同实体对象的相同索引

使用 Hibernate @Index Annotation 在 DB 上创建索引

您是不是需要在 Hibernate 表的 @id 列上创建索引

休眠中索引和@NaturalId之间的区别

尝试在休眠中映射 Map<Integer,String> 时唯一索引或主键冲突

MySQL 索引相关知识详解