Hi,
I posted the same issue on the hibernate site, but am cross-posting here because it may be spring that I'm getting into difficulty with.
I'm having some difficulty getting a many-to-one relation initialized. I'm subclassing HibernateDaoSupport class in the class involved.
What I have is a Batch that contains a Set of transactions. In a certain method I want to load a batch using hibernate by calling the getHibernateTemplate().findByNamedParam() method, passing in the id of the batch. I also need the set of transactions in this case, which I get back by doing a left join fetch in the hql passed in to the spring method mentioned (this is the reason I use hql - I need to specify a left join fetch)
This all works fine. However here I get into trouble. Each Transaction has 2 many-to-one relations (a transactionCurrency and an errorCode) that I want initialized by this query. I thought the best way to do this was by iterating through the transactions and calling a Hibernate.initialize() for each many-to-one I was interested in initializing. However this seems only to work for the transactionCurrency many-to-one (even though the hibernate-generated select SQL for both many-to-ones appears on the console).
The code snippet below uses a hardcoded transactional callback. I've tried using a TransactionProxyFactoryBean as well with the same results.
The errorCode object is always a cglib proxy with null values for both its fields. I'm sure I'm doing something stupid here or there is a trivial mistake in my mappings or transaction. I'd be grateful if anyone could point any problem out, cause I can't see it.
Here's the spring code
Code:public Batch getBatchWithTransactions(final Long batchID) { return (Batch) getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(final Session session) { Batch batch = (Batch) session.createQuery( "from myproject.dataobject.Batch b " + "left join fetch b.transactions " + "where b.id = :batchID").setParameter("batchID", batchID) .list().get(0); Iterator txns = batch.getTransactions().iterator(); while (txns.hasNext()) { Transaction t = (Transaction) txns.next(); Hibernate.initialize(t.getErrorCode()); Hibernate.initialize(t.getTransactionCurrency()); } return batch; } }); }
(relevant parts of 4 different hbm.xml files)
Batch.hbm.xml
transaction.hbm.xmlCode:<hibernate-mapping> <class name="myproject.dataobject.Batch" table="batch"> <id name="id" column="batch_id" type="long"> <generator class="native" /> </id> <set name="transactions" inverse="true" cascade="save-update"> <key column="batch_id" /> <one-to-many class="myproject.dataobject.Transaction" /> </set> </class> </hibernate-mapping>
StatusCode.hbm.xmlCode:<hibernate-mapping package="myproject.dataobject"> <class name="Transaction" table="TRANSACTION"> <id column="TRANSACTION_ID" name="id" type="long" > <generator class="native" /> </id> <many-to-one name="batch" not-null="true" class="myproject.dataobject.Batch" cascade="save-update" > <column name="BATCH_ID" /> </many-to-one> <many-to-one name="errorCode" class="myproject.dataobject.lookup.StatusCode" column="ERROR_CODE" /> <many-to-one name="transactionCurrency" class="myproject.dataobject.Currency" column="TRANSACTION_CURRENCY_CODE" /> </class> </hibernate-mapping>
Currency.hbm.xmlCode:<hibernate-mapping package="myproject.dataobject"> <class name="StatusCode" table="STATUS_CODE"> <id column="ERROR_CODE" name="id" type="integer" > <generator class="native" /> </id> <property column="ERROR_DESCRIPTION" length="50" name="description" not-null="false" type="string" /> </class> </hibernate-mapping>
Code:<hibernate-mapping> <class name="myproject.dataobject.Currency" table="currency"> <id name="isoCode" column="iso_code" type="integer"> <generator class="sequence"> <param name="sequence">acquirer_comm_seq</param> </generator> </id> <property name="swiftCode" column="swift_code" not-null="true" type="string" unique="false" /> <property name="name" column="description" not-null="true" type="string" unique="false" /> <property name="minorUnits" column="minor_units" not-null="true" type="integer" unique="false" /> </class> </hibernate-mapping>


Reply With Quote
) that hibernate overrode the accessors and set a dirty flag on the setters.