Simple app works wrong with following entity structure
@Entity(name="some_table")
@Inheritance(strategy= InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn( name="TYPE", discriminatorType=DiscriminatorType.STRING )
abstract class EntityBase {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column
private int id;
}
@Entity
@DiscriminatorValue("EntityA")
@Cacheable
class EntityA extends EntityBase {
@Column
private int aColumn;
...
}
@Entity
@DiscriminatorValue("EntityB")
@Cacheable
class EntityB extends EntityBase {
@Column
private int bColumn;
...
}
@Entity(name="holder_table")
@Cacheable
class HolderEntity {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column
private int id;
@ManyToOne(fetch=FetchType.LAZY)
EntityBase holdedEntity;
...
}
For first load or without cache everything works well
After loading of HolderEntity instance from cache, holdedEntity field initialised by object with type EntityBase (abstract class).
Pseudocode:
def a = HolderEntity.get(1)
assert a.holdedEntity.class!=EntityBase a = HolderEntity.get(1) assert a.holdedEntity.class!=EntityBase
During loading from cache hibernate construct entity using special logic: for field it detect class type by variable type (it's EntityBase class) instead of discriminator (final Type[] types = subclassPersister.getPropertyTypes(); in DefaultLoadEventListener) and call method SessionImpl.internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) witch "instantiate" abstract class and init fields by data from hibernate cache
It works same for lazy & eager loading of holdedEntity Class type stored in AbstractEntityPersister.EntityMetamodel. It looks like, field type for cache is static, but it's should depend on instance of field
How to solve it without disabling of hibernate L2 cache?
Test case https://github.com/demon101/hibernate-l2-inheritence https://github.com/demon101/hibernate-l2-inheritence/blob/master/src/test/java/com/test/hibernate/L2InheritanceTest.java
|