DuplicateMappingException при преобразовании стратегии наследования из InheritanceType.JOINED в InheritanceType.SINGLE_TABLE - PullRequest
1 голос
/ 09 июля 2020

Проблема: у меня есть устаревшее приложение, содержащее один абстрактный суперкласс (скажем, Task) и более 50 подклассов, называемых SubTask1, и так далее. Кроме того, у этих подклассов есть различные поля с одинаковыми именами, например filename, user et c. Более того, эти подклассы имеют различные отношения @ManyToOne с одним классом (допустим, Property).

Теперь, как инструмент ORM, мы используем hibernate со стратегией наследования как JOINED. Теперь производительность запросов для этих сущностей очень низкая. Следовательно, для повышения производительности я пытаюсь изменить стратегию наследования на SINGLE_TABLE и позволить спящему режиму генерировать схему.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
abstract public class Task {
    public String type;

    //Getters and setters
}

@Entity 
public class SubTask1 extends Task {
    public subTask1Field;
    public String user;
    public string filename;
    @ManyToOne(optional = false)
    public Property host;
    //Getters and setters

}

@Entity 
public class SubTask2 extends Task {
    public subTask2Field;

    public String user;
    public string filename;
    @ManyToOne(optional = false)
    public Property host;
    //Getters and setters

}

@Entity
public class Property {
    @Unique
    @Required
    public String name;

    @Required
    public String value;    
}

Проблема: во время запуска приложения я получаю исключение ниже.

2020-07-09 12:18:26,665 ERROR --- [                     main] play                           :   Can't start in PROD mode with errors
javax.persistence.PersistenceException: Unable to build EntityManagerFactory
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:925)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:900)
        at play.db.jpa.JPAPlugin.onApplicationStart(JPAPlugin.java:204)
        at play.plugins.PluginCollection.onApplicationStart(PluginCollection.java:616)
        at play.Play.start(Play.java:538)
        at play.Play.init(Play.java:309)
        at play.server.Server.main(Server.java:160)
Caused by: org.hibernate.DuplicateMappingException:  Table [Task] contains logical column name [fileName] referenced by multiple physical column names: [`filename`], [`fileName`]
        at org.hibernate.cfg.Configuration$MappingsImpl$TableColumnNameBinding.bindLogicalToPhysical(Configuration.java:3021)
        at org.hibernate.cfg.Configuration$MappingsImpl$TableColumnNameBinding.addBinding(Configuration.java:3008)
        at org.hibernate.cfg.Configuration$MappingsImpl.addColumnBinding(Configuration.java:3053)
        at org.hibernate.cfg.Ejb3Column.addColumnBinding(Ejb3Column.java:330)
        at org.hibernate.cfg.Ejb3Column.linkWithValue(Ejb3Column.java:322)
        at org.hibernate.cfg.annotations.SimpleValueBinder.linkWithValue(SimpleValueBinder.java:361)
        at org.hibernate.cfg.annotations.SimpleValueBinder.make(SimpleValueBinder.java:336)
        at org.hibernate.cfg.annotations.PropertyBinder.makePropertyAndValue(PropertyBinder.java:193)
        at org.hibernate.cfg.annotations.PropertyBinder.makePropertyValueAndBind(PropertyBinder.java:205)
        at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2166)
        at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:895)
        at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:728)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3625)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3579)
        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1381)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1786)
        at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:918)
        ... 6 common frames omitted
Exception in thread "main" play.exceptions.UnexpectedException: Unexpected Error
        at play.Play.start(Play.java:568)
        at play.Play.init(Play.java:309)
        at play.server.Server.main(Server.java:160)
Caused by: javax.persistence.PersistenceException: Unable to build EntityManagerFactory
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:925)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:900)
        at play.db.jpa.JPAPlugin.onApplicationStart(JPAPlugin.java:204)
        at play.plugins.PluginCollection.onApplicationStart(PluginCollection.java:616)
        at play.Play.start(Play.java:538)
        ... 2 more
Caused by: org.hibernate.DuplicateMappingException:  Table [Task] contains logical column name [fileName] referenced by multiple physical column names: [`filename`], [`fileName`]
        at org.hibernate.cfg.Configuration$MappingsImpl$TableColumnNameBinding.bindLogicalToPhysical(Configuration.java:3021)
        at org.hibernate.cfg.Configuration$MappingsImpl$TableColumnNameBinding.addBinding(Configuration.java:3008)
        at org.hibernate.cfg.Configuration$MappingsImpl.addColumnBinding(Configuration.java:3053)
        at org.hibernate.cfg.Ejb3Column.addColumnBinding(Ejb3Column.java:330)
        at org.hibernate.cfg.Ejb3Column.linkWithValue(Ejb3Column.java:322)
        at org.hibernate.cfg.annotations.SimpleValueBinder.linkWithValue(SimpleValueBinder.java:361)
        at org.hibernate.cfg.annotations.SimpleValueBinder.make(SimpleValueBinder.java:336)
        at org.hibernate.cfg.annotations.PropertyBinder.makePropertyAndValue(PropertyBinder.java:193)
        at org.hibernate.cfg.annotations.PropertyBinder.makePropertyValueAndBind(PropertyBinder.java:205)
        at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2166)
        at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:895)
        at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:728)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3625)
        at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3579)
        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1381)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1786)
        at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
        at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:918)
        ... 6 more

Вопросы:

  1. возможно ли преобразовать такую ​​стратегию наследования без внесения изменений в мои классы Entity? Если да, то какие изменения вы предложите по этому поводу?
  2. Есть ли здесь какой-либо другой способ улучшить производительность запросов? всякий раз, когда я пытаюсь получить объект Task, он создает соединение для всех таблиц SubTask, причем каждая таблица SubTask объединяется с таблицей Property.

1 Ответ

0 голосов
/ 09 июля 2020

Проблема: [filename], [fileName] У вас один и тот же атрибут записан в разных регистрах.

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