org.hibernate.WrongClassException в наследовании одной таблицы при обновлении с hibernate 4 до 5.2.17 - PullRequest
0 голосов
/ 26 июня 2018

У меня есть следующие классы:

@Entity
@Table(name = "TranzitOfficeLayer")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, include = "all")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "DTYPE", discriminatorType = DiscriminatorType.STRING)
@DiscriminatorOptions(force = true)
public abstract class OfficeLayer implements Serializable, ir.customs.saloon.OfficeLayer, Cloneable {
...
}

@Entity
@Table(name = "EstelamAzDarbKhorujLayer")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, include = "all")
@DiscriminatorValue("EstelamAzDarbKhorujLayer")
public class EstelamAzDarbKhorujLayer extends OfficeLayer implements Serializable {

    @Basic(optional = true)
    @Cache(include = "all", usage = CacheConcurrencyStrategy.READ_WRITE)
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @Fetch(FetchMode.SUBSELECT)
    @JoinTable(name = "TranzitOfficeLayer_DarbeKhorujOfficeLayers",
            joinColumns = @JoinColumn(name = "TranzitOfficeLayer_dbId", referencedColumnName = "dbId"),
            inverseJoinColumns = @JoinColumn(name = "darbeKhorujOfficeLayerses_serialNum", referencedColumnName = "serialNum"))
    private Collection<DarbeKhorujOfficeLayers> darbeKhorujOfficeLayerses;

    public Collection<DarbeKhorujOfficeLayers> getDarbeKhorujOfficeLayerses() {
        if (darbeKhorujOfficeLayerses == null) {
            return new LinkedList<>();
        }
        return darbeKhorujOfficeLayerses;
    }
}

@Entity
@Table(name = "EstelamAzDarbKhorujVaredat")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, include = "all")
@DiscriminatorValue("EstelamAzDarbKhorujVaredat")
public class EstelamAzDarbKhorujVaredat extends EstelamAzDarbKhorujLayer {
}

@Entity
@Table(name = "EstelamAzDarbkhorujSaderat")
@DiscriminatorValue(value = "EstelamAzDarbKhorujSaderat")
public class EstelamAzDarbKhorujSaderat extends EstelamAzDarbKhorujVaredat {
}

Когда я вызываю getDarbeKhorujOfficeLayerses() метод из EstelamAzDarbKhorujLayer класса в середине открытого сеанса, выдается следующее исключение:

Caused by: org.hibernate.WrongClassException: Object [id=194759] was not of the specified subclass [EstelamAzDarbKhorujSaderat] : loaded object was of wrong class class EstelamAzDarbKhorujVaredat
    at org.hibernate.loader.plan.exec.process.internal.EntityReferenceInitializerImpl.hydrateEntityState(EntityReferenceInitializerImpl.java:190)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.readRow(AbstractRowReader.java:103)
    at org.hibernate.loader.plan.exec.internal.EntityLoadQueryDetails$EntityLoaderRowReader.readRow(EntityLoadQueryDetails.java:241)
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:122)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
    at org.hibernate.loader.entity.plan.AbstractLoadPlanBasedEntityLoader.load(AbstractLoadPlanBasedEntityLoader.java:167)
    at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4121)
    at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:508)
    at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:478)
    at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:219)
    at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:278)
    at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:121)
    at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:89)
    at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1240)
    at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:1123)
    at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:682)
    at org.hibernate.type.EntityType.resolve(EntityType.java:464)
    at org.hibernate.type.ManyToOneType.resolve(ManyToOneType.java:239)
    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:171)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:128)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.performTwoPhaseLoad(AbstractRowReader.java:238)
    at org.hibernate.loader.plan.exec.process.internal.AbstractRowReader.finishUp(AbstractRowReader.java:209)
    at org.hibernate.loader.plan.exec.process.internal.ResultSetProcessorImpl.extractResults(ResultSetProcessorImpl.java:133)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:122)
    at org.hibernate.loader.plan.exec.internal.AbstractLoadPlanBasedLoader.executeLoad(AbstractLoadPlanBasedLoader.java:86)
    at org.hibernate.loader.collection.plan.AbstractLoadPlanBasedCollectionInitializer.initialize(AbstractLoadPlanBasedCollectionInitializer.java:87)
    at org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:688)
    at org.hibernate.event.internal.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:75)
    at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2223)
    at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:565)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:247)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:561)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132)
    at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:277)

Значение столбца DTYPE в базе данных равно EstelamAzDarbKhorujVaredat, но, похоже, hibernate пытается идентифицировать этот объект как EstelamAzDarbKhorujSaderat.

Также, когда я нахожусь в режиме отладки и вычисляю значение в реальном времени поля darbeKhorujOfficeLayerses для точки останова, это исключение не генерируется.

Этот код прекрасно работал в hibernate 4, но при обновлении до hibernate 5.2.17 это произошло. Я искал много дней, чтобы найти решение, но ни один из них не сработал. Заранее спасибо!

1 Ответ

0 голосов
/ 26 июня 2018

Проблема вызвана ЧЧХ-4742 . Просто убедитесь, что вы не загружаете сущность базовым классом только для того, чтобы потом попытаться загрузить ее по ее подклассу.


@DiscriminatorValue является избыточным в ваших сопоставлениях, поскольку в любом случае соответствует имени класса. Попробуйте удалить его.

Также @DiscriminatorOptions#force необходимо, когда :

таблица содержит строки с дополнительными значениями дискриминатора, которые не являются сопоставлены с постоянным классом

Если это не так, удалите это тоже.

Если это не помогло, попробуйте скопировать его, как описано в этой статье .

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