3

I have bellow classes:

@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 {
}

When I call getDarbeKhorujOfficeLayerses() method from EstelamAzDarbKhorujLayer class in middle of an open session bellow exception is thrown:

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)

The value of DTYPE column in database is EstelamAzDarbKhorujVaredat but it seems hibernate tries to identify this object as EstelamAzDarbKhorujSaderat.

Also when I'm in debug mode and I calculate the real time value of darbeKhorujOfficeLayerses field on a breakpoint, that exception does not throw.

This code was perfectly worked in hibernate 4 but when I upgrade to hibernate 5.2.17 this occurred. I've searched many days to find a solution but none of them have worked. Thank you in advance!

  • Try seeing if this [post](https://stackoverflow.com/questions/31257027/org-hibernate-wrongclassexception-on-saving-an-entity-via-hibernate) helps – soufrk Jun 26 '18 at 13:54
  • @soufrk thanks but the post you mentioned is about problems of generics and I'm not using generics in my code. – arian reyhaneh Jun 26 '18 at 14:42
  • Looks like a hibernate proxy issue. Can you post the code where you call "getDarbeKhorujOfficeLayerses". Also, I see the @MappedSuperclass annotation is missing. – Nullbeans Jun 26 '18 at 16:22
  • @A.Ebrahim that piece of code is so complicated and it's in some nested classes. Can you tell me what are you looking for? – arian reyhaneh Jun 27 '18 at 06:38
  • I wanted to see how you call getDarbeKhorujOfficeLayerses. Is it from a superclass instance? a subclass instance? how is the instance initialized? – Nullbeans Jun 27 '18 at 08:47
  • @A.Ebrahim I call `getDarbeKhorujOfficeLayerses()` in an instance of `EstelamAzDarbKhorujLayer ` class. – arian reyhaneh Jun 27 '18 at 10:16

1 Answers1

2

The issue is caused by HHH-4742. Just make sure you don't load an entity by the base class only to reload it afterward by its subclass.


The @DiscriminatorValue is redundant in your mappings because it matches the class name anyway. Try removing it.

Also, @DiscriminatorOptions#force is needed when:

the table contains rows with extra discriminator values that are not mapped to a persistent class

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911