hello newsgroup,
i've been getting a PropertyValueException when i try to save a graph of objects that are cascaded with save-update.
i've got an account object with sets of customers, orders and transactions. It also a reference to one of the customers who is the principal account holder.
This is where the problem lies, as when i try to save a new account with the principal holder property set, hibernate will then set the account references of the new orders and transactions to null.
can someone have a look at this and tell me where the problem may lie. i haven't included the classes, but they are simple java beans with only the methods descibed in the mapping file.
thanks, cam
Code:
<hibernate-mapping>
<class name="com.account.test.Account" table="Account">
<id name="id" column="id" type="java.lang.Long" >
<generator class="hilo"/>
</id>
<many-to-one name="principalHolder"
class="com.account.test.Customer" cascade="save-update"
outer-join="auto" not-null="false" />
<set name="accountHolders" table="AccountGroup" lazy="true"
inverse="false" cascade="save-update" sort="unsorted" >
<key column="account" />
<many-to-many class="com.account.test.Customer"
column="customer" outer-join="auto" />
</set>
<set name="transactions" lazy="true" inverse="true"
cascade="save-update" sort="unsorted" >
<key column="account" />
<one-to-many class="com.account.test.Transaction" />
</set>
<set name="orders" lazy="true" inverse="true" cascade="save-update"
sort="unsorted" >
<key column="account" />
<one-to-many class="com.account.test.Order" />
</set>
</class>
<class name="com.account.test.Order" table="Orders" >
<id name="id" column="id" type="java.lang.Long" >
<generator class="hilo"/>
</id>
<version name="version" type="int" column="version" />
<many-to-one name="account" class="com.account.test.Account"
cascade="save-update" outer-join="auto" update="true" insert="true"
column="account" not-null="true" />
</class>
<class name="com.account.test.Transaction" table="Transaction" mutable="false" >
<id name="id" column="id" type="java.lang.Long" >
<generator class="hilo"/>
</id>
<version name="version" type="int" column="version" />
<many-to-one name="account" class="com.account.test.Account"
cascade="save-update" outer-join="auto" update="true" insert="true"
column="account" not-null="true" />
<many-to-one name="customer" class="com.account.test.Customer"
cascade="save-update" outer-join="false" update="true" insert="true"
column="customer" not-null="false" />
</class>
<class name="com.account.test.Customer" table="Customer"
dynamic-update="true" dynamic-insert="true" >
<id name="id" column="id" type="java.lang.Long" >
<generator class="hilo"/>
</id>
<discriminator column="customerType" type="string" length="7" />
<set name="accounts" table="AccountGroup" lazy="true" inverse="true"
cascade="save-update" sort="unsorted" >
<key column="customer" />
<many-to-many class="com.account.test.Account" column="account"
outer-join="auto" />
</set>
<set name="transactions" lazy="true" inverse="true"
cascade="save-update" sort="unsorted" >
<key column="customer" />
<one-to-many class="com.account.test.Transaction" />
</set>
</class>
</hibernate-mapping>
Code:
Session session = null;
net.sf.hibernate.Transaction sessionTransaction = null;
try {
Account account = new Account();
Customer customer = new Customer();
Set accounts = new HashSet();
accounts.add(account);
customer.setAccounts(accounts);
Set customers = new HashSet();
customers.add(customer);
account.setAccountHolders(customers);
account.setPrincipalHolder(customer);
Order order = new Order();
order.setAccount(account);
Set orders = new HashSet();
orders.add(order);
account.setOrders(orders);
Transaction transaction = new Transaction();
transaction.setAccount(account);
transaction.setCustomer(customer);
Set customerTrans = new HashSet();
customerTrans.add(transaction);
customer.setTransactions(customerTrans);
Set trans = new HashSet();
trans.add(transaction);
account.setTransactions(trans);
session = factory.openSession();
sessionTransaction = session.beginTransaction();
session.save(account);
sessionTransaction.commit();
} catch (Exception e) {
e.printStackTrace();
sessionTransaction.rollback();
} finally {
session.close();
}
Code:
16:33:17,219 DEBUG SessionImpl:528 - opened session
16:33:17,249 DEBUG JDBCTransaction:37 - begin
16:33:17,259 DEBUG DriverManagerConnectionProvider:78 - total checked-out connections: 0
16:33:17,299 DEBUG DriverManagerConnectionProvider:84 - using pooled JDBC connection, pool size: 0
16:33:17,309 DEBUG JDBCTransaction:41 - current autocommit status:false
16:33:17,329 DEBUG DriverManagerConnectionProvider:78 - total checked-out connections: 1
16:33:17,339 DEBUG DriverManagerConnectionProvider:94 - opening new JDBC connection
16:33:19,212 DEBUG DriverManagerConnectionProvider:100 - created connection to: jdbc:mysql://electric.serve.co.uk/wiscotland, Isolation Level: 2
16:33:19,803 DEBUG DriverManagerConnectionProvider:114 - returning connection to pool, pool size: 1
16:33:19,803 DEBUG TableHiLoGenerator:62 - new hi value: 678
16:33:19,833 DEBUG SessionImpl:786 - saving [com.account.test.Account#22216705]
16:33:19,863 DEBUG Cascades:497 - processing cascades for: com.account.test.Account
16:33:19,893 DEBUG Cascades:113 - cascading to saveOrUpdate()
16:33:19,893 DEBUG SessionImpl:1321 - saveOrUpdate() unsaved instance
16:33:19,903 DEBUG DriverManagerConnectionProvider:78 - total checked-out connections: 1
16:33:19,903 DEBUG DriverManagerConnectionProvider:84 - using pooled JDBC connection, pool size: 0
16:33:20,393 DEBUG DriverManagerConnectionProvider:114 - returning connection to pool, pool size: 1
16:33:20,393 DEBUG TableHiLoGenerator:62 - new hi value: 679
16:33:20,403 DEBUG SessionImpl:786 - saving [com.account.test.Customer#22249473]
16:33:20,403 DEBUG Cascades:497 - processing cascades for: com.account.test.Customer
16:33:20,403 DEBUG Cascades:506 - done processing cascades for: com.account.test.Customer
16:33:20,453 DEBUG Cascades:497 - processing cascades for: com.account.test.Customer
16:33:20,474 DEBUG Cascades:524 - cascading to collection: com.account.test.Customer.accounts
16:33:20,494 DEBUG Cascades:113 - cascading to saveOrUpdate()
16:33:20,494 DEBUG SessionImpl:1306 - saveOrUpdate() persistent instance
16:33:20,504 DEBUG Cascades:524 - cascading to collection: com.account.test.Customer.transactions
16:33:20,514 DEBUG Cascades:113 - cascading to saveOrUpdate()
16:33:20,514 DEBUG SessionImpl:1321 - saveOrUpdate() unsaved instance
16:33:20,514 DEBUG DriverManagerConnectionProvider:78 - total checked-out connections: 1
16:33:20,524 DEBUG DriverManagerConnectionProvider:84 - using pooled JDBC connection, pool size: 0
16:33:21,014 DEBUG DriverManagerConnectionProvider:114 - returning connection to pool, pool size: 1
16:33:21,024 DEBUG TableHiLoGenerator:62 - new hi value: 680
16:33:21,024 DEBUG SessionImpl:786 - saving [com.account.test.Transaction#22282241]
16:33:21,024 DEBUG Cascades:497 - processing cascades for: com.account.test.Transaction
16:33:21,044 DEBUG Cascades:113 - cascading to saveOrUpdate()
16:33:21,044 DEBUG SessionImpl:1306 - saveOrUpdate() persistent instance
16:33:21,054 DEBUG Cascades:113 - cascading to saveOrUpdate()
16:33:21,054 DEBUG SessionImpl:1306 - saveOrUpdate() persistent instance
16:33:21,054 DEBUG Cascades:506 - done processing cascades for: com.account.test.Transaction
net.sf.hibernate.PropertyValueException: not-null property references a null or transient value: com.account.test.Transaction.account
at net.sf.hibernate.impl.SessionImpl.checkNullability(SessionImpl.java:1211)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:873)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:817)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:740)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:717)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1322)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascadeCollection(Cascades.java:526)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:452)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:892)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:817)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:740)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:717)
at net.sf.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:1322)
at net.sf.hibernate.engine.Cascades$4.cascade(Cascades.java:114)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:436)
at net.sf.hibernate.engine.Cascades.cascade(Cascades.java:503)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:843)
at net.sf.hibernate.impl.SessionImpl.doSave(SessionImpl.java:817)
at net.sf.hibernate.impl.SessionImpl.saveWithGeneratedIdentifier(SessionImpl.java:740)
at net.sf.hibernate.impl.SessionImpl.save(SessionImpl.java:717)
at com.account.test.AccountTest.<init>(AccountTest.java:76)
at com.account.test.AccountTest.main(AccountTest.java:89)
16:33:21,144 DEBUG JDBCTransaction:82 - rollback
16:33:21,275 DEBUG SessionImpl:558 - transaction completion
16:33:21,285 DEBUG SessionImpl:546 - closing session
16:33:21,285 DEBUG SessionImpl:3187 - disconnecting session
16:33:21,295 DEBUG DriverManagerConnectionProvider:114 - returning connection to pool, pool size: 2
16:33:21,295 DEBUG SessionImpl:558 - transaction completion