My best guess is that hibernate is trying to deserialize a plain number as if it were a serialized object. The number is 367 and the invalid stream header is 7868081F.
I'm using POJOs as domain entities in a grails project by putting them in the lib directory. Then I update my hibernate.cfg.xml to list the POJOs.
This works for one set of POJOs generated by Netbeans some time ago, but the more recent POJOs generated by hibernate are not working.
The exception I'm getting is bellow and comes from this line of code:
List<ModelView> models = ModelView.findAll()
The exception:
java.io.StreamCorruptedException: invalid stream header: 7868081F
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:801)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:298)
at org.hibernate.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:328)
at org.hibernate.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:318)
at org.hibernate.util.SerializationHelper.doDeserialize(SerializationHelper.java:237)
at org.hibernate.util.SerializationHelper.deserialize(SerializationHelper.java:306)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:130)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:116)
at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:39)
at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:62)
at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:254)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:250)
at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:230)
at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:331)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2283)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1527)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1455)
at org.hibernate.loader.Loader.getRow(Loader.java:1355)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611)
at org.hibernate.loader.Loader.doQuery(Loader.java:829)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
at org.hibernate.loader.Loader.doList(Loader.java:2542)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.ListPersistentMethod$1.doInHibernate(ListPersistentMethod.java:76)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
at org.springframework.orm.hibernate3.HibernateTemplate.executeFind(HibernateTemplate.java:343)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.ListPersistentMethod.doInvokeInternal(ListPersistentMethod.java:56)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractStaticPersistentMethod.invoke(AbstractStaticPersistentMethod.java:72)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.AbstractStaticPersistentMethod.invoke(AbstractStaticPersistentMethod.java:65)
at org.codehaus.groovy.grails.commons.metaclass.StaticMethodInvocation$invoke.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
at org.codehaus.groovy.grails.orm.hibernate.HibernateGormStaticApi.list(HibernateGormEnhancer.groovy:320)
at org.grails.datastore.gorm.GormStaticApi.findAll(GormStaticApi.groovy:404)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1265)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1082)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:1106)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:906)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:848)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:831)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:164)
at org.grails.datastore.gorm.StaticMethodInvokingClosure.call(GormEnhancer.groovy:288)
at org.codehaus.groovy.runtime.metaclass.ClosureStaticMetaMethod.invoke(ClosureStaticMetaMethod.java:59)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite$StaticMetaMethodSiteNoUnwrapNoCoerce.invoke(StaticMetaMethodSite.java:148)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:88)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
Here's a working POJO from Netbeans. I've, of course, renamed everything to match the new name ModelView
. This POJO has the old name Model
.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.integrativebioinformatics.processdb.entities;
import java.io.Serializable;
import java.math.BigInteger;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author jzwolak
*/
@Entity
@Table(name = "MODEL_VIEW")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Model.findAll", query = "SELECT m FROM Model m"),
@NamedQuery(name = "Model.findByModelId", query = "SELECT m FROM Model m WHERE m.modelId = :modelId"),
@NamedQuery(name = "Model.findByModelDescription", query = "SELECT m FROM Model m WHERE m.modelDescription = :modelDescription"),
@NamedQuery(name = "Model.findByPersonId", query = "SELECT m FROM Model m WHERE m.personId = :personId"),
@NamedQuery(name = "Model.findByUserName", query = "SELECT m FROM Model m WHERE m.userName = :userName"),
@NamedQuery(name = "Model.findByPublicFlag", query = "SELECT m FROM Model m WHERE m.publicFlag = :publicFlag"),
@NamedQuery(name = "Model.findByUserId", query = "SELECT m FROM Model m WHERE m.userId = :userId"),
@NamedQuery(name = "Model.findByVersionDate", query = "SELECT m FROM Model m WHERE m.versionDate = :versionDate"),
@NamedQuery(name = "Model.findBySecurityLevel", query = "SELECT m FROM Model m WHERE m.securityLevel = :securityLevel"),
@NamedQuery(name = "Model.findByOrganizationId", query = "SELECT m FROM Model m WHERE m.organizationId = :organizationId"),
@NamedQuery(name = "Model.findByLayoutStyle", query = "SELECT m FROM Model m WHERE m.layoutStyle = :layoutStyle"),
@NamedQuery(name = "Model.findByNotes", query = "SELECT m FROM Model m WHERE m.notes = :notes"),
@NamedQuery(name = "Model.findByNoteText", query = "SELECT m FROM Model m WHERE m.noteText = :noteText")})
public class Model implements Serializable {
private static final long serialVersionUID = 1L;
@Basic(optional = false)
@Column(name = "MODEL_ID")
@Id
private BigInteger modelId;
@Basic(optional = false)
@Column(name = "MODEL_DESCRIPTION")
private String modelDescription;
@Basic(optional = false)
@Column(name = "PERSON_ID")
private BigInteger personId;
@Column(name = "USER_NAME")
private String userName;
@Column(name = "PUBLIC_FLAG")
private String publicFlag;
@Column(name = "USER_ID")
private String userId;
@Column(name = "VERSION_DATE")
@Temporal(TemporalType.TIMESTAMP)
private Date versionDate;
@Column(name = "SECURITY_LEVEL")
private BigInteger securityLevel;
@Basic(optional = false)
@Column(name = "ORGANIZATION_ID")
private BigInteger organizationId;
@Column(name = "LAYOUT_STYLE")
private String layoutStyle;
@Column(name = "NOTES")
private String notes;
@Column(name = "NOTE_TEXT")
private String noteText;
@Column(name = "LAST_MODIFIED")
@Temporal(TemporalType.TIMESTAMP)
private Date lastModified;
public Model() {
}
public BigInteger getModelId() {
return modelId;
}
public void setModelId(BigInteger modelId) {
this.modelId = modelId;
}
public String getModelDescription() {
return modelDescription;
}
public void setModelDescription(String modelDescription) {
this.modelDescription = modelDescription;
}
public BigInteger getPersonId() {
return personId;
}
public void setPersonId(BigInteger personId) {
this.personId = personId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPublicFlag() {
return publicFlag;
}
public void setPublicFlag(String publicFlag) {
this.publicFlag = publicFlag;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Date getVersionDate() {
return versionDate;
}
public void setVersionDate(Date versionDate) {
this.versionDate = versionDate;
}
public BigInteger getSecurityLevel() {
return securityLevel;
}
public void setSecurityLevel(BigInteger securityLevel) {
this.securityLevel = securityLevel;
}
public BigInteger getOrganizationId() {
return organizationId;
}
public void setOrganizationId(BigInteger organizationId) {
this.organizationId = organizationId;
}
public String getLayoutStyle() {
return layoutStyle;
}
public void setLayoutStyle(String layoutStyle) {
this.layoutStyle = layoutStyle;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public String getNoteText() {
return noteText;
}
public void setNoteText(String noteText) {
this.noteText = noteText;
}
public Date getLastModified() {
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
}
Here's the equivalent failing POJO:
package com.integrativebioinformatics.processdb.generated.entities;
// Generated Dec 5, 2013 12:01:06 PM by Hibernate Tools 4.0.0
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* ModelView generated by hbm2java
*/
@Entity
@Table(name="MODEL_VIEW"
,schema="PROCESSDB_DEV"
)
public class ModelView implements java.io.Serializable {
private BigDecimal modelId;
private String modelDescription;
private BigDecimal personId;
private String userName;
private String publicFlag;
private String userId;
private BigDecimal baseModelId;
private Date versionDate;
private BigDecimal securityLevel;
private BigDecimal organizationId;
private String layoutStyle;
private String notes;
private String noteText;
private Serializable lastModified;
public ModelView() {
}
public ModelView(BigDecimal modelId, String modelDescription, BigDecimal personId, BigDecimal organizationId) {
this.modelId = modelId;
this.modelDescription = modelDescription;
this.personId = personId;
this.organizationId = organizationId;
}
public ModelView(BigDecimal modelId, String modelDescription, BigDecimal personId, String userName, String publicFlag, String userId, BigDecimal baseModelId, Date versionDate, BigDecimal securityLevel, BigDecimal organizationId, String layoutStyle, String notes, String noteText, Serializable lastModified) {
this.modelId = modelId;
this.modelDescription = modelDescription;
this.personId = personId;
this.userName = userName;
this.publicFlag = publicFlag;
this.userId = userId;
this.baseModelId = baseModelId;
this.versionDate = versionDate;
this.securityLevel = securityLevel;
this.organizationId = organizationId;
this.layoutStyle = layoutStyle;
this.notes = notes;
this.noteText = noteText;
this.lastModified = lastModified;
}
@Id
@Column(name="MODEL_ID", nullable=false, precision=22, scale=0)
public BigDecimal getModelId() {
return this.modelId;
}
public void setModelId(BigDecimal modelId) {
this.modelId = modelId;
}
@Column(name="MODEL_DESCRIPTION", nullable=false, length=240)
public String getModelDescription() {
return this.modelDescription;
}
public void setModelDescription(String modelDescription) {
this.modelDescription = modelDescription;
}
@Column(name="PERSON_ID", nullable=false, precision=22, scale=0)
public BigDecimal getPersonId() {
return this.personId;
}
public void setPersonId(BigDecimal personId) {
this.personId = personId;
}
@Column(name="USER_NAME", length=30)
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name="PUBLIC_FLAG", length=1)
public String getPublicFlag() {
return this.publicFlag;
}
public void setPublicFlag(String publicFlag) {
this.publicFlag = publicFlag;
}
@Column(name="USER_ID", length=30)
public String getUserId() {
return this.userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
@Column(name="BASE_MODEL_ID", precision=22, scale=0)
public BigDecimal getBaseModelId() {
return this.baseModelId;
}
public void setBaseModelId(BigDecimal baseModelId) {
this.baseModelId = baseModelId;
}
@Temporal(TemporalType.DATE)
@Column(name="VERSION_DATE", length=7)
public Date getVersionDate() {
return this.versionDate;
}
public void setVersionDate(Date versionDate) {
this.versionDate = versionDate;
}
@Column(name="SECURITY_LEVEL", precision=22, scale=0)
public BigDecimal getSecurityLevel() {
return this.securityLevel;
}
public void setSecurityLevel(BigDecimal securityLevel) {
this.securityLevel = securityLevel;
}
@Column(name="ORGANIZATION_ID", nullable=false, precision=22, scale=0)
public BigDecimal getOrganizationId() {
return this.organizationId;
}
public void setOrganizationId(BigDecimal organizationId) {
this.organizationId = organizationId;
}
@Column(name="LAYOUT_STYLE", length=1)
public String getLayoutStyle() {
return this.layoutStyle;
}
public void setLayoutStyle(String layoutStyle) {
this.layoutStyle = layoutStyle;
}
@Column(name="NOTES", length=3000)
public String getNotes() {
return this.notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
@Column(name="NOTE_TEXT", length=2000)
public String getNoteText() {
return this.noteText;
}
public void setNoteText(String noteText) {
this.noteText = noteText;
}
@Column(name="LAST_MODIFIED")
public Serializable getLastModified() {
return this.lastModified;
}
public void setLastModified(Serializable lastModified) {
this.lastModified = lastModified;
}
}
You'll notice that baseModelId
does not appear in the older Model
but does appear in ModelView
and this seems to be where the problem is. The database view contains BASE_MODEL_ID
(which is a foreign key for the underlying table), but Netbeans chose not to map it and hibernate does map it. I would like it mapped.
The relevant log output from Grails is
2013-12-05 11:52:22,959 [http-bio-8080-exec-11] DEBUG hibernate.GrailsHibernateTemplate - Found thread-bound Session for HibernateTemplate
2013-12-05 11:52:22,966 [http-bio-8080-exec-11] DEBUG jdbc.AbstractBatcher - about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2013-12-05 11:52:22,967 [http-bio-8080-exec-11] DEBUG jdbc.ConnectionManager - opening JDBC connection
2013-12-05 11:52:22,998 [http-bio-8080-exec-11] DEBUG hibernate.SQL - select this_.model_id as model1_3_0_, this_.base_model_id as base2_3_0_, this_.last_modified as last3_3_0_, this_.layout_style as layout4_3_0_, this_.model_description as model5_3_0_, this_.note_text as note6_3_0_, this_.notes as notes3_0_, this_.organization_id as organiza8_3_0_, this_.person_id as person9_3_0_, this_.public_flag as public10_3_0_, this_.security_level as security11_3_0_, this_.user_id as user12_3_0_, this_.user_name as user13_3_0_, this_.version_date as version14_3_0_ from PROCESSDB_DEV.model_view this_
2013-12-05 11:52:22,998 [http-bio-8080-exec-11] TRACE jdbc.AbstractBatcher - preparing statement
2013-12-05 11:52:23,045 [http-bio-8080-exec-11] TRACE loader.Loader - Bound [1] parameters total
2013-12-05 11:52:23,071 [http-bio-8080-exec-11] DEBUG jdbc.AbstractBatcher - about to open ResultSet (open ResultSets: 0, globally: 0)
2013-12-05 11:52:23,071 [http-bio-8080-exec-11] TRACE loader.Loader - processing result set
2013-12-05 11:52:23,071 [http-bio-8080-exec-11] DEBUG loader.Loader - result set row: 0
2013-12-05 11:52:23,073 [http-bio-8080-exec-11] TRACE sql.BasicExtractor - found [369] as column [model1_3_0_]
2013-12-05 11:52:23,073 [http-bio-8080-exec-11] DEBUG loader.Loader - result row: EntityKey[com.integrativebioinformatics.processdb.generated.entities.ModelView#369]
2013-12-05 11:52:23,073 [http-bio-8080-exec-11] TRACE loader.Loader - Initializing object from ResultSet: [com.integrativebioinformatics.processdb.generated.entities.ModelView#369]
2013-12-05 11:52:23,075 [http-bio-8080-exec-11] TRACE entity.AbstractEntityPersister - Hydrating entity: [com.integrativebioinformatics.processdb.generated.entities.ModelView#369]
2013-12-05 11:52:23,075 [http-bio-8080-exec-11] TRACE sql.BasicExtractor - found [367] as column [base2_3_0_]
2013-12-05 11:52:23,076 [http-bio-8080-exec-11] TRACE util.SerializationHelper - Starting deserialization of object
2013-12-05 11:52:23,077 [http-bio-8080-exec-11] DEBUG jdbc.AbstractBatcher - about to close ResultSet (open ResultSets: 1, globally: 1)
2013-12-05 11:52:23,077 [http-bio-8080-exec-11] DEBUG jdbc.AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
2013-12-05 11:52:23,077 [http-bio-8080-exec-11] TRACE jdbc.AbstractBatcher - closing statement
2013-12-05 11:52:23,078 [http-bio-8080-exec-11] TRACE jdbc.JDBCContext - after autocommit
2013-12-05 11:52:23,078 [http-bio-8080-exec-11] DEBUG jdbc.ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!
2013-12-05 11:52:23,078 [http-bio-8080-exec-11] TRACE impl.SessionImpl - after transaction completion
2013-12-05 11:52:23,082 [http-bio-8080-exec-11] DEBUG hibernate.GrailsHibernateTemplate - Not closing pre-bound Hibernate Session after HibernateTemplate
| Error 2013-12-05 11:52:23,090 [http-bio-8080-exec-11] ERROR errors.GrailsExceptionResolver - StreamCorruptedException occurred when processing request: [GET] /processdb/model
invalid stream header: 7868081F. Stacktrace follows:
Message: invalid stream header: 7868081F
Line | Method
->> 801 | readStreamHeader in java.io.ObjectInputStream
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 298 | <init> in ''
| 404 | findAll . . . . in org.grails.datastore.gorm.GormStaticApi
| 288 | call in org.grails.datastore.gorm.StaticMethodInvokingClosure
| 25 | model . . . . . in processdb.ProcessDBController$$EOPB6oLI
| 195 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter . . . . in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run in java.lang.Thread
In the database view BASE_MODEL_ID
is of type NUMBER
(it's an Oracle DB).
Is it true? Is Hibernate trying to deserialize a plain number from the database column?
Update
Just to check, I removed baseModelId from the POJO (and its getters and setters). The log output no longer has the line
sql.BasicExtractor - found [367] as column [base2_3_0_]
And I still get the util.SerializationHelper and StreamCorruptedException.
Now I think it may be the lastModified property because it somehow got the type Serializable
.