Hello,
I am struggling with Spring MVC and Hibernate. I'm about to throw up my hands and call it quits and resort to straight JDBC code. Here is the fundamental problem: saving to the database.
I currently am using the OpenSessionInView filter with singleSession set to false. Now, let's say I have a Customer object which contains a Contact object which has all of the customer's contact info. Customer is stored in table CUSTOMER which has a foreign key for the CONTACT_ID which points to CONTACT. Now, contact in turn, has a many:1 relationship with table STATE, a separate java object as well.
So, I'm looking at this:
Code:
Customer (lazy="true"):
public Contact getContact()
public void setContact(Contact contact)
Contact (lazy = "true"):
public State getState()
public void setState(State state)
State (no proxy or lazy):
...
Now, when I display the view for the user to edit the customer, there are absolutely no problems. This display has 2 dropdowns, both have a list of states and are stored in separate fields in the contact object, one for shipping and one for billing. When the user submits and tries to perform the save, I have a custom propertyeditor which converts the state ids to State objects. Everything works so far. However, when I go and save the customer to the database I get an error:
Quote:
object references an unsaved transient instance - save the transient instance before flushing
Ok, so I did some reading and saw that you have to reassociate the object with the session, so i did that using session.lock. However, there is a huge problem with this, if the billing and shipping states are the same you cannot lock the same object twice.
Quote:
a different object with the same identifier value was already associated with the session: 3, of class: com.flipswap.domain.State; nested exception is net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
So what do I do now? Do I have to compare the two state objects and if they are the same only lock one? So, does this mean that I'm going to have to do this for all of my objects? Couldn't this headache be solved by using DTOs, passing them into the service layer which then converts them to the domain object appropriately. Everyone keeps saying DTOs are evil, but I'm starting to feel that using Domain objects in the view are the devil reincarnate. What is everyone else doing to fix this issue?
Thoughts?
Thanks,
Rexxe
Hibernate version: 2.1.7
Mapping documents: Code:
Customer:
<many-to-one
name="contact"
class="foo.domain.Contact"
cascade="all"
outer-join="true"
update="true"
insert="true"
access="property"
foreign-key="FK_CONTACT_ID"
column="CONTACT_ID"
not-null="true"
unique="true"
/>
Contact:
<many-to-one
name="state"
class="foo.domain.State"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="primary_address_state"
/>
Code between sessionFactory.openSession() and session.close():
session.saveOrUpdateCopy(entity);
Full stack trace of any exception that occurs: See above
Name and version of the database you are using: PostgreSQL 8.0