I have problem loading tables from database while using DiscriminatorColumn. As far as there is entity extending my super class (ObjectA), there is no problem with data loading. Problem occurred when new values appeared in discriminator column which do not have it table extension. I am trying to load ObjctA with discriminator value different than it is specified in annotation (ObjectTypes.GENERIC_OBJECT). Since I am using IngeritanceType.JOINED I know there should be a child table with the id to join these tables, but there is no such table. I can not add it also (requirements).
What I am trying to do, is to load ObjectA classes with discriminator value different than specified in annotation. I know that Value accepts only one value. I also tried to create empty class that extends ObjectA, and set dicriminator value to desired one. No success. Hibernate treat that as entity and can not find it.
Is there any workaround for that scenario?
My entities looks like this:
@MappedSuperclass
public abstract class AbstractEntity implements Serializable
{...
@Entity
@Table(name = "objecta")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "objectclass", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorValue(ObjectTypes.GENERIC_OBJECT)
@NamedQueries({...})
public class ObjectA extends AbstractEntity {
...
@Entity
@Table(name = "objectb")
@DiscriminatorValue(ObjectTypes.OBJECT_B)
@NamedQueries({...})
public class ObjectB extends ObjectA{
public class ObjectTypes{
public static final String GENERIC_OBJECT = "0";
public static final String OBJECT_B= "1";
public static final String OBJECT_C = "2";//no extension table for that object type,
//it is the same as GENERI_OBJECT (no additional properties)
public static final String OBJECT_C = "3";
...}
(edit)Issue:
I can not load ObjectA objects by executing native queries (but I can load it when ObjectA is loaded as child object extension):
@NamedQueries({ @NamedQuery(name = ObjectA.FIND_BY_ID, query = "SELECT t FROM ObjectA t WHERE t.id = :id"),
@NamedQuery(name = ObjectA.FIND_ALL, query = "SELECT t FROM ObjectA t"),
@NamedQuery(name = ObjectA.TOTAL_RESULT, query = "SELECT count(t) from ObjectA t"),
@NamedQuery(name = ObjectA.FIND_BY_OBJECT_TYPE, query = "SELECT t FROM ObjectA t WHERE t.objecttype = :objectType") })
public class ObjectA extends AbstractEntity {
private static final long serialVersionUID = 8831394270398606926L;
public static final String FIND_BY_ID = "ObjectA.find";
public static final String FIND_ALL = "ObjectA.findAll";
...
//loading part
public List<ObjectA> findByObjectType(ObjectTypes objectType) {
return em.createNamedQuery(ObjectA.FIND_BY_OBJECT_TYPE, ObjectA.class).setParameter("objectType", objectType).getResultList();
}
Stack trace:
Caused by: javax.persistence.PersistenceException: org.hibernate.type.SerializationException: could not deserialize
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:492)
at com.mypackage.repository.ObjectARepository.findAll(ObjectARepository.java:38)
at com.mypackage.database.DatabaseManager.init(DatabaseManager.java:77)
... 240 more
Caused by: org.hibernate.type.SerializationException: could not deserialize
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:243)
at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:138)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:113)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:27)
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter$2.extract(AttributeConverterSqlTypeDescriptorAdapter.java:121)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:238)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:234)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:224)
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:300)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2738)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1729)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1655)
at org.hibernate.loader.Loader.getRow(Loader.java:1544)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:727)
at org.hibernate.loader.Loader.processResultSet(Loader.java:972)
at org.hibernate.loader.Loader.doQuery(Loader.java:930)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:336)
at org.hibernate.loader.Loader.doList(Loader.java:2617)
at org.hibernate.loader.Loader.doList(Loader.java:2600)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2429)
at org.hibernate.loader.Loader.list(Loader.java:2424)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:501)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:371)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:216)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1326)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:87)
at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:606)
at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:483)
... 242 more
Caused by: java.io.StreamCorruptedException: invalid stream header: 7B227363
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:806)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:309)
at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:299)
at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:218)
... 272 more
When using InheritanceType.JOINED
there is no need for a DiscriminatorColumn
(this is meant for SINGLE_TABLE
inheritance).
For InheritanceType.JOINED
, you will need the following in your subclass:
@PrimaryKeyJoinColumn(name = "parent_id", referencedColumnName = "id")
The table for your subclass will then need a column parent_id
, which is both the primary key
for the table, and a foreign key
for the column id
(primary key) in the table corresponding to the superclass.