When a type (that I can't identify from the error messages) attempts to cascade a relation to another type (that I can't identify until I modify the error messages), I get a message which indicates that Hibernate can't figure out how to resolve a java.lang.Long into an identifier.
Here is the original stack trace and the modified stack trace. In both cases, you can safely ignore the com.accruent exception (it's included for calling context).
Code:
[java] Caused by: com.accruent.orm.PersistenceException: exception caught while preparing hibernate transaction (flush any cached changes to db).
[java] at com.accruent.orm.impl.HibernateTransactionWrapper.doPrepare(HibernateTransactionWrapper.java:191)
[java] at com.accruent.txn.impl.TransactionAC.prepare(TransactionAC.java:108)
[java] ... 34 more
[java] Caused by: net.sf.hibernate.MappingException: No persister for: java.lang.Long
[java] at net.sf.hibernate.impl.SessionFactoryImpl.getPersister(SessionFactoryImpl.java:420)
[java] at net.sf.hibernate.impl.SessionImpl.getPersister(SessionImpl.java:2302)
[java] at net.sf.hibernate.impl.SessionImpl.getPersister(SessionImpl.java:2309)
[java] at net.sf.hibernate.impl.SessionImpl.getEntityIdentifierIfNotUnsaved(SessionImpl.java:2374)
[java] at net.sf.hibernate.type.EntityType.getIdentifier(EntityType.java:56)
[java] at net.sf.hibernate.type.EntityType.isDirty(EntityType.java:124)
[java] at net.sf.hibernate.type.TypeFactory.findDirty(TypeFactory.java:210)
[java] at net.sf.hibernate.persister.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:209)
[java] at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2182)
[java] at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2017)
[java] at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2004)
[java] at com.accruent.orm.impl.HibernateTransactionWrapper.doPrepare(HibernateTransactionWrapper.java:185)
[java] ... 35 more
Since this exception is pretty useless, I inserted a more informative exception in the EntityType class to produce this stack trace:
Code:
[java] Caused by: com.accruent.orm.PersistenceException: exception caught while preparing hibernate transaction (flush any cached changes to db).
[java] at com.accruent.orm.impl.HibernateTransactionWrapper.doPrepare(HibernateTransactionWrapper.java:191)
[java] at com.accruent.txn.impl.TransactionAC.prepare(TransactionAC.java:108)
[java] ... 36 more
[java] Caused by: net.sf.hibernate.HibernateException: in type 'com.accruent.base.impl.AbstractResource', an attempt to resolve the identifier '3835' failed with exception.: No persister for: java.lang.Long
[java] at net.sf.hibernate.type.EntityType.getIdentifier(EntityType.java:60)
[java] at net.sf.hibernate.type.EntityType.isDirty(EntityType.java:130)
[java] at net.sf.hibernate.type.TypeFactory.findDirty(TypeFactory.java:210)
[java] at net.sf.hibernate.persister.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:209)
[java] at net.sf.hibernate.impl.SessionImpl.flushEntities(SessionImpl.java:2182)
[java] at net.sf.hibernate.impl.SessionImpl.flushEverything(SessionImpl.java:2017)
[java] at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2004)
[java] at com.accruent.orm.impl.HibernateTransactionWrapper.doPrepare(HibernateTransactionWrapper.java:185)
[java] ... 37 more
[java] Caused by: net.sf.hibernate.MappingException: No persister for: java.lang.Long
[java] at net.sf.hibernate.impl.SessionFactoryImpl.getPersister(SessionFactoryImpl.java:420)
[java] at net.sf.hibernate.impl.SessionImpl.getPersister(SessionImpl.java:2302)
[java] at net.sf.hibernate.impl.SessionImpl.getPersister(SessionImpl.java:2309)
[java] at net.sf.hibernate.impl.SessionImpl.getEntityIdentifierIfNotUnsaved(SessionImpl.java:2374)
[java] at net.sf.hibernate.type.EntityType.getIdentifier(EntityType.java:57)
[java] ... 44 more
The only other clue that I have is that some types were incorrectly using property tags instead of a many-to-one tags. I tried to eliminate all of the errant references and change them to many-to-one. I don't know if this issue is related to that problem or something else.
Any hints as to what might be going on here? Why can't AbstractResource convert a java.lang.Long into it's identifier here (even though that type passes many other unit tests, including full CRUD tests)?
I don't think it will do much good (since I think the problem is in one of the two dozen types that refers to resource), but here's the mapping file for AbstractResource:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<!-- Commitment mapping definition -->
<class name="com.accruent.base.impl.AbstractResource"
table="ORI_RESOURCE"
mutable="true"
polymorphism="implicit">
<id name="objectId" column="RESOURCE_OID" type="long">
<generator class="native">
<param name="sequence">next_oid</param>
</generator>
</id>
<many-to-one name="parent" column="PARENT_FK"
class="com.accruent.base.impl.AbstractResource"/>
<set name="fragmentSet" table="ORI_RESOURCE">
<key column="PARENT_FK"/>
<one-to-many class="com.accruent.base.impl.AbstractResource"/>
</set>
<set name="contractSet" table="CONTRACT_RESOURCE_MM">
<key column="RESOURCE_FK"/>
<many-to-many column="CONTRACT_FK"
class="com.accruent.base.impl.Contract"/>
</set>
<set name="controllerSet" table="RESOURCE_CONTROLLER_MM">
<key column="RESOURCE_FK"/>
<many-to-many column="AGENT_FK"
class="com.accruent.base.impl.AbstractAgent"/>
</set>
<set name="commitmentSet" table="ATOMIC_CMTMT">
<key column="RESOURCE_FK"/>
<one-to-many class="com.accruent.base.impl.AtomicCommitment"/>
</set>
<set name="eventSet" table="EVENT">
<key column="RESOURCE_FK"/>
<one-to-many class="com.accruent.base.impl.Event"/>
</set>
<joined-subclass name="com.accruent.finance.impl.Account"
table="FIN_ACCOUNT">
<key column="ACCOUNT_OID"/>
<property name="accountNumber" column="ACCOUNT_NUMBER" type="string"/>
<property name="routingNumber" column="ROUTING_NUMBER" type="string"/>
</joined-subclass>
<joined-subclass name="com.accruent.realestate.impl.LeasableSpace"
table="RE_SPACE">
<key column="SPACE_OID"/>
<property name="name" column="SPACE_NAME" type="string"/>
<many-to-one name="location" column="LOCATION_FK" cascade="save-update"
class="com.accruent.realestate.impl.Location"/>
<component name="area">
<property name="amount" column="AREA" type="big_decimal"/>
</component>
<component name="rent">
<property name="amount" column="RENT" type="big_decimal"/>
</component>
</joined-subclass>
</class>
</hibernate-mapping>
Any hints? Has anyone seen anything like this before?
Regards,
Ross