I am upgrading Hibernate 3 to Hibernate 4.1. When running the application, I got below exception:
java.lang.AbstractMethodError
at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:124)
at org.hibernate.type.AbstractType.hydrate(AbstractType.java:106)
at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2701)
at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1541)
at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1473)
at org.hibernate.loader.Loader.getRow(Loader.java:1373)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:640)
at org.hibernate.loader.Loader.doQuery(Loader.java:850)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2042)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3710)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:439)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:420)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:204)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:251)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:148)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:992)
at org.hibernate.internal.SessionImpl.internalLoad(SessionImpl.java:919)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:610)
at org.hibernate.type.EntityType.resolve(EntityType.java:438)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:150)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:995)
at org.hibernate.loader.Loader.doQuery(Loader.java:874)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doList(Loader.java:2447)
at org.hibernate.loader.Loader.listUsingQueryCache(Loader.java:2292)
at org.hibernate.loader.Loader.list(Loader.java:2255)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1161)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
at my.com.MyDAOImpl.findDocuments(MyDaoImpl.java:22)......
I understand Hibernate4 changed parameters in nullSafeGet() and nullSafeSet(). So I have to override these methods using new parameters and ignored SessionImplementor in customized type implemetation anyway.
findDocuments() basically query documents from Documents table, none of the fields of Document.hmb.xml has customized type. My puzzle is why CustomType.nullSafeGet() is called? In Document.hmb.xml, there is only one suspect but I am not sure at the moment as after I changed the type to "Blob" and got same error.
<property name="image" column="PICTURE" type="org.springframework.orm.hibernate3.support.BlobByteArrayType"/>
Can you please help?
My question is resolved by changing "org.springframework.orm.hibernate3.support.BlobByteArrayType to "materialized_blob.
<property name="image" column="PICTURE" type="materialized_blob"/>
It looks like Spring implemenation calls Hibernate 3 CustomType.java which conflicts with the Hibernate 4 CustomType.java. One lesson learned, when upgrading Hibernate 3 to 4, blob column needs to use "materialized_blob" as type, which is much simpler solution than Hibernate 3, Spring has to put a lobHandler inside sessionFactory.
Related
Using EclipseLink 2.6.0 on WebLogic 12.2.1.4.0 I started to get the following exception upon invoking EntityManager.merge()
java.lang.NullPointerException: null
at org.eclipse.persistence.descriptors.changetracking.AttributeChangeTrackingPolicy.updateListenerForSelfMerge(AttributeChangeTrackingPolicy.java:130)
at org.eclipse.persistence.mappings.CollectionMapping.mergeIntoObject(CollectionMapping.java:1642)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.mergeIntoObject(ObjectBuilder.java:4136)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:601)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:313)
at org.eclipse.persistence.mappings.CollectionMapping.mergeIntoObject(CollectionMapping.java:1638)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.mergeIntoObject(ObjectBuilder.java:4136)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:601)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:313)
at org.eclipse.persistence.mappings.CollectionMapping.mergeIntoObject(CollectionMapping.java:1638)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.mergeIntoObject(ObjectBuilder.java:4136)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:601)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:313)
at org.eclipse.persistence.mappings.ObjectReferenceMapping.mergeIntoObject(ObjectReferenceMapping.java:499)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.mergeIntoObject(ObjectBuilder.java:4136)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChangesOfCloneIntoWorkingCopy(MergeManager.java:601)
at org.eclipse.persistence.internal.sessions.MergeManager.mergeChanges(MergeManager.java:313)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3524)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.mergeCloneWithReferences(RepeatableWriteUnitOfWork.java:387)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.mergeCloneWithReferences(UnitOfWorkImpl.java:3484)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.mergeInternal(EntityManagerImpl.java:553)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.merge(EntityManagerImpl.java:530)
at weblogic.persistence.BasePersistenceContextProxyImpl.invoke(BasePersistenceContextProxyImpl.java:97)
at weblogic.persistence.TransactionalEntityManagerProxyImpl.invoke(TransactionalEntityManagerProxyImpl.java:164)
at weblogic.persistence.BasePersistenceContextProxyImpl.invoke(BasePersistenceContextProxyImpl.java:86)
at com.sun.proxy.$Proxy5085.merge(Unknown Source)
at com.acme.dao.Dao.save(Dao.java:86)
I found a workaround which is setting
<property name="eclipselink.weaving.changetracking" value="false"/>
in persistence.xml
However, this disables weaving changetracking for the whole persistence unit which might have an undesired global impact.
The transaction involves a bunch of objects with twisted #ManyToOne(fetch = FetchType.LAZY) relationships and the exception is thrown only when trying to delete one of the objects and merging another.
My question is: is it possible to disable weaving changetracking only for the entities involved in the transaction where the NullPointerException occurs?
I have tried adding #Mutable annotations on the fields and all types of #ChangeTracking on the entities but none of those eliminated the NullPointerException.
I am attempting to create a new hibernate entity using annotations within a legacy spring project. All of the previous existing entities were defined using .hbm.xml files. I am finding though that my new annotated entity is unable to make references to the legacy .hbm defined ones.
Since this is a spring project this was added into the sessionFactory bean in order to allow my new entity to be resolved by the session factory.
<property name="mappingResources" ref="mappingResources"/>
<property name="packagesToScan" value="com.project"/>
In my new object I made a single reference to an old entity like this
#ManyToOne
#JoinColumn(name = "oldEntityId")
private OldEntity old;
The old entity, which is picked up fine using the legacy method, is unable to be retrieved via hibernate from the new annotated entity.
Now when the entities are initialized this exception is thrown:
Caused by: org.hibernate.AnnotationException: #OneToOne or #ManyToOne on com.project...NewEntity references an unknown entity: com.project...OldEntity
If I attempt to simply add an #Entity annotation to the OldEntity, that error is replaced with a duplicate entity message.
If there is anything which I may be missing here or what I am trying to accomplish is impossible please let me know.
Spring Ver: org.springframework:spring-core:4.3.14.RELEASE
Hibernate Ver: org.hibernate:hibernate-core:4.1.7.Final
Edit:
Turns out if I use the old hbm.xml method everything works seamlessly. I am only having a problem with the annotated method.
I have recently changed an object to have a #OneToMany mapping to another object, with the FetchType.LAZY. But when I try to load a list of these objects using a #NamedNativeQuery, which calls an Oracle function, it throws a java.sql.SQLException: Invalid column name for this new OneToMany mapping. But being marked as LAZY, it shouldn't try to populate this variable should it?
In theory I could change the function to return an empty value for this column (basically a hack), but I would have to roll that out to everywhere that uses a #NamedNativeQuery to populate one of these objects.
This seems like a bug to me. Is there a workaround, something I'm missing or possibly fixed in a later version of Hibernate?
I'm using hibernate-core 3.3.2.GA, hibernate-entitymanager 3.4.0.GA, hibernate-annotations 3.4.0.GA and hibernate-commons-annotations 3.3.0.ga.
I just set up a basic hibernate/spring project to test some stuff. I use a MySQL db by using WAMP.
These are all of the classes: http://codepaste.net/7pwmtx
This is my bean definition and pom file: http://codepaste.net/4iz7jb
POM is a little bit messy but this is the problem: I think that I set up my dialect properly because I get no errors when i add something to the db. I get errors when I use find in hql. I t seems like hibernate isnt retrieving data from the same place that it is putting it. Any idea why this doesnt work?
By the way, the console output was:
Exception in thread "main" org.springframework.orm.hibernate3.HibernateQueryException: hobject is not mapped [from hobject]; nested exception is org.hibernate.hql.ast.QuerySyntaxException: hobject is not mapped [from hobject]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:660)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:912)
at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:904)
at hibernate.dao.SpringHibernateOperatorImplementation.getAllRows(SpringHibernateOperatorImplementation.java:24)
at hibernate.main.HibernateMain.main(HibernateMain.java:22)
Caused by: org.hibernate.hql.ast.QuerySyntaxException: hobject is not mapped [from hobject]
at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:181)
at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:110)
at org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:93)
at org.hibernate.hql.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:277)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3056)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:2945)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:688)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:544)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:281)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:229)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:251)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:183)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:134)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:94)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1650)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:914)
at org.springframework.orm.hibernate3.HibernateTemplate$30.doInHibernate(HibernateTemplate.java:1)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406)
... 5 more
Add the entity class hibernate.dao.HObject to hibernate.cfg.xml files. It is neeeded even if you are using annotation based configurations.
If you want to skip adding these to cfg file you can use the approach mentioned here provided you are using spring.
I have a legacy application that uses hibernate for mapping objects into a database. It uses the Hibernate Mapping XML file to do so. The java class contains two properties abc and def that implement java Serializable. The mapping is defined this way:
<property name="abc" column="ABC" type="serializable" length="32672"/>
<property name="def" column="DEF" type="serializable" length="32672"/>
When I try to set this up with oracle, I get a nasty error "ORA-01754: a table may contain only one column of type LONG" which essentially is complaining about creating two 'long raw' columns in one table. Oracle does not like this. After reading up on the issue, the recommended approach is to use blobs instead of 'long raw' types.
My question is, how can I express in the hibernate mapping file to use a serializable type mapped into a blob column? I would think there would be a serializable_blob type but there does not seem to be.
I know this is possible with JPA annotations using #Basic and #Lob. It should also be possible using the hibernate mapping file. How can this be done in the hibernate mapping file?
Update:
The following do not work as Serializable works:
type=binary - This one expects a byte[]. Does not work for Serializable classes. Gives ClassCastException.
type=blob - - This one expects a java.sql.Blob. Does not work for Serializable classes. Gives ClassCastException.
type=materialized_blob - - This one expects a byte[]. Does not work for Serializable classes. Gives ClassCastException.
<property
name="data"
type="blob"
column="DATA"/>
...
should work.
Ok, did some more research following my comment above and, by Jove, I found it.
In Hibernate 3.5 + Spring 3.1, I used Spring's org.springframework.orm.hibernate3.support.BlobSerializableType. Now I'm upgrading to Hibernate 4.3, that option isn't available anymore. I did find the type to column mappings as OP, but in my application there are various Strings (legacy) that are mapped to BLOB fields.
So, as I reported in the comment above, I found the org.hibernate.type.SerializableToBlob type, which is parameterize. Below how I got the mapping to work (using good old-fashioned hbm.xml mappings)
<property name="description" column="TEXT">
<type name="org.hibernate.type.SerializableToBlobType">
<param name="classname">java.lang.String</param>
</type>
</property>
And that appears to do the trick. (the classname value should be the type of the attribute you are mapping, I think)