Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an index with JPA/hibernate and use fields from MappedSuperClass together with fields from concrete entity

I have the @MappedSuperClass (simplified example):

@MappedSuperclass
public abstract class MySuperClass {

    @Id
    @GeneratedValue
    private long id;

    @Column(nullable = false)
    private Date creationDate;

    // ...
}

and a concrete Entity (simplified example):

@Entity
public class MyEntity extends MySuperClass {
    @Index(name = "IDX_MYINDEX")
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private MyType type;

    @Index(name = "IDX_MYINDEX")
    @Column(nullable = false)
    @Enumerated(EnumType.STRING)
    private MyResult status;

    // ...
}

Now I need an index including the columns MySuperClass.creationDate, MyEntity.status and MyEntity.type.

If I add @Index(name = "IDX_MYINDEX") to MySuperClass.creationDate hibernate adds an index of creationDate to every Entity inherited from MySuperClass.

I tried @AttributeOverride but it is not capable for indexes.

Any ideas?

like image 440
t777 Avatar asked Jul 24 '14 20:07

t777


People also ask

Can we use JPA and Hibernate together?

You cant actually use both of them in the same application.

Does Hibernate use index?

As the others already mentioned: Hibernated doesn't decide to use or not use an index. Your database does.

What is index in Hibernate?

Indexing. The short answer is that indexing is automatic: Hibernate Search will transparently index every entity each time it's persisted, updated or removed through Hibernate ORM. Its mission is to keep the index and your database in sync, allowing you to forget about this problem.

Which annotation in JPA is placed on the collection reference in the entity class?

The JPA specification requires the @Entity annotation. It identifies a class as an entity class. You can use the name attribute of the @Entity annotation to define the name of the entity.


3 Answers

If you are using JPA 2.1 then you can use class annotation @Table with its attribute indexes

@Table(indexes = { @Index(name = "IDX_MYIDX1", columnList = "id,name,surname") })

Please note that as documentation says

These are only used if table generation is in effect. Defaults to no additional indexes.

columnlist, as shown above, accepts column names list as a comma-delimited list.

If you don't use JPA 2.1 you can just use old Hibernates @Index annotation (note this is already deprecated). There's attribute columnNames where you can pass array of column names no matter above which field it is declared.

@Index(name = "IDX_MYIDX1", columnNames = { "id", "name", "surname"})
like image 180
Maciej Dobrowolski Avatar answered Oct 02 '22 12:10

Maciej Dobrowolski


Use @Index annotation and use the parameter "columnList" to set which columns should be used to make your index. That list should be made of a comma-separated list of values of the column names.

Important: Don't forget to add the column name property (via Column annotation) to all properties that make this index, otherwise you'll get an error when starting up your container.

like image 35
dontForgetTheJoker Avatar answered Oct 02 '22 12:10

dontForgetTheJoker


Make sure list column names that you've given in @Column's name attribute not fields' names.

Also enabling ddl-auto to update will create all the indexes.

spring.jpa.hibernate.ddl-auto=update

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "ANSWER_OPTION", indexes = {@Index(name="SEC_INDEX",columnList = "ID,SEQUENCE,QUESTION_ID,OPTION_TITLE")})
public class AnswerOptionEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "SEQUENCE")
private Long sequence;

@Column(name = "OPTION_TITLE")
private String optionTitle;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "QUESTION_ID", nullable = false)
@JsonIgnore
private QuestionEntity questionEntity;

@OneToMany(mappedBy = "answerOptionEntity", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnore
private List<ResultEntity> resultEntityList = new ArrayList<>();

}

like image 38
D B Avatar answered Oct 01 '22 12:10

D B