Hibernate继承问题
Hibernate inheritance issue
我在使用 DiscriminatorColumn 时从数据库加载 table 时遇到问题。只要有entity extending my super class (ObjectA),数据加载就没有问题。当新值出现在没有 table 扩展名的鉴别器列中时,就会出现问题。我正在尝试使用不同于注释中指定的鉴别器值加载 ObjctA (ObjectTypes.GENERIC_OBJECT)。由于我使用的是 IngeritanceType.JOINED 我知道应该有一个 child table 和 id 来加入这些 table,但是没有这样的 table。我也不能添加它(要求)。
我想要做的是加载 ObjectA classes,其鉴别器值不同于注释中指定的值。我知道 Value 只接受一个值。我还尝试创建空 class 来扩展 ObjectA,并将鉴别器值设置为所需值。没有成功。 Hibernate 将其视为实体并且无法找到它。
这种情况有什么解决方法吗?
我的实体如下所示:
@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";
...}
(编辑)问题:
我无法通过执行本机查询来加载 ObjectA objects(但当 ObjectA 作为 child object 扩展加载时我可以加载它):
@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();
}
堆栈跟踪:
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.doExtract(VarbinaryTypeDescriptor.java:60)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter.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
使用 InheritanceType.JOINED
时不需要 DiscriminatorColumn
(这是为了 SINGLE_TABLE
继承)。
对于 InheritanceType.JOINED
,您的子类中需要以下内容:
@PrimaryKeyJoinColumn(name = "parent_id", referencedColumnName = "id")
您的子类的 table 将需要一列 parent_id
,它既是 table 的 primary key
又是 foreign key
的 foreign key
table 中的列 id
(主键)对应于超类。
我在使用 DiscriminatorColumn 时从数据库加载 table 时遇到问题。只要有entity extending my super class (ObjectA),数据加载就没有问题。当新值出现在没有 table 扩展名的鉴别器列中时,就会出现问题。我正在尝试使用不同于注释中指定的鉴别器值加载 ObjctA (ObjectTypes.GENERIC_OBJECT)。由于我使用的是 IngeritanceType.JOINED 我知道应该有一个 child table 和 id 来加入这些 table,但是没有这样的 table。我也不能添加它(要求)。
我想要做的是加载 ObjectA classes,其鉴别器值不同于注释中指定的值。我知道 Value 只接受一个值。我还尝试创建空 class 来扩展 ObjectA,并将鉴别器值设置为所需值。没有成功。 Hibernate 将其视为实体并且无法找到它。
这种情况有什么解决方法吗?
我的实体如下所示:
@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";
...}
(编辑)问题:
我无法通过执行本机查询来加载 ObjectA objects(但当 ObjectA 作为 child object 扩展加载时我可以加载它):
@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();
}
堆栈跟踪:
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.doExtract(VarbinaryTypeDescriptor.java:60)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47)
at org.hibernate.type.descriptor.converter.AttributeConverterSqlTypeDescriptorAdapter.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
使用 InheritanceType.JOINED
时不需要 DiscriminatorColumn
(这是为了 SINGLE_TABLE
继承)。
对于 InheritanceType.JOINED
,您的子类中需要以下内容:
@PrimaryKeyJoinColumn(name = "parent_id", referencedColumnName = "id")
您的子类的 table 将需要一列 parent_id
,它既是 table 的 primary key
又是 foreign key
的 foreign key
table 中的列 id
(主键)对应于超类。