Использование индексной аннотации в суперклассе с Hibernate - PullRequest
1 голос
/ 15 февраля 2020

У меня есть абстрактный суперкласс, каждый объект которого в моем домене является его подклассом.

Используя генерацию схемы БД, я хочу создать индекс для каждого объекта на поле в суперклассе и без него. использование аннотации таблицы для каждого подкласса.

Мой суперкласс

    @MappedSuperclass
    public abstract class BaseEntity {

        @Id
        @GeneratedValue(strategy = SEQUENCE)
        private Long surrogateId;

        @Index(name="id_index") // Every subclass should inherit this index, with its own name
        @Column(unique = true, updatable = false, nullable = false)
        private UUID id = UUID.randomUUID();

Пример подкласса

    @Entity
    public class Customer extends BaseEntity {
        ...
    }

Я пробовал до сих пор:

  • использует аннотацию Table с @Index на суперклассе, но Hibernate, похоже, не использует эту аннотацию, если она не помечена @Entity. Например, @Table(indexes = {@Index(name="index_id", columnList = "id")}) Нет SQL операторов.

  • использовать аннотацию устарел @ Index с именем "id_index", но создается только один индекс при запуске (БД выдает ошибку, что этот индекс уже существует для других объектов). Некоторые сгенерированные SQL заявления:

    Hibernate: create index id_index on "customer" ("id")

    Hibernate: create index id_index on "user" ("id")

    2020-02-15 17:47:26,620 WARN  o.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl    - GenerationTarget encountered exception accepting command : Error executing DDL "create index id_index on "customer" ("id")" via JDBC Statement
    org.postgresql.util.PSQLException: ERROR: relation "id_index" already exists

Есть идеи, как это сделать без слишком большого дублирования кода?

Спасибо

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Единственный способ, которым я могу убедиться в этом - и это кажется более сложным, чем просто избегать размещения аннотации @Table на каждом объекте, - это создать собственный диалект и переопределить метод getIndexExporter():

public class MyPostgreSQLDialect extends PostgreSQLXXDialect{

    @Override
    public Exporter<Index> getIndexExporter() {
            return new MyIndexExporter(this);
        }
    }

для возврата настроенного экспортера, вероятнее всего расширяющего org.hibernate.tool.schema.internal.StandardIndexExporter

public class MyIndexExporter extends StandardIndexExporter{

    public MyIndexExporter(Dialect dialect){
        super(dialect);
    }        

    @Override
    public String[] getSqlCreateStrings(Index index, Metadata metadata) {
      //looks like you'd need to paste the whole code from superclass method
      //and alter the index name accordingly

      indexNameForCreation = index.getTable().getQualifiedTableName() + 
               "_" + index.getName();

      //in the default implementation it is simply index.getName()
    }
}
0 голосов
/ 19 февраля 2020

Alan Hay ответ может сработать, но кажется, что это слишком сложный метод ... Поэтому я решил не использовать генерацию схемы и вместо этого использовать Liquibase , чтобы иметь больше возможностей контролировать база данных.

В любом случае, если у кого-то возникла такая же проблема с генерацией схемы, я попытался с @ Index (используя eclipselink), и это сработало, поэтому эта проблема есть только в Hibernate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...