[a]Hibernate version:3.1.1
[b]Name and version of the database you are using:PotgreSQL1.8.2
We have a multi-screen application, which contains a multi-step wizard.
The application is a Spring MVC and Webflow application having multiple wizard-like pages.
The application maintains conversational state with the screen. On each step of the wizard, we update the database with the current state of the domain objects.
The Database Structure is
• Project (Primary Key: projectId)
• Refdata (Primary key: refdata_Id)
• ProjectRefdata is a many-to-many join with only two columns (project_id, refdata_id). Both columns form the composite key.
There are various types of reference data (the type is represented by the Type column in RefData table).
The relevant Hibernate mappings are as follows –
// Mapping for Servicelines (Reference Data items with type “SL”)
<bag name="serviceLines" table="PROJECT_REFDATA"
cascade="merge">
<key column="PROJECT_ID" />
<many-to-many column="REFDATA_ID"
class="com.accenture.adsj.credentials.domain.reference.ServiceLine"
where="TYPE='SL'" />
</bag>
// Mapping for Domain Specialties (Reference Data items with type “DS”)
<bag name="domainSpecialties" table="PROJECT_REFDATA"
cascade="merge">
<key column="PROJECT_ID" />
<many-to-many column="REFDATA_ID"
class="com.accenture.adsj.credentials.domain.reference.DomainSpecialty"
where="TYPE='DS'" />
</bag>
The Project domain object has collections of ServiceLines and DomainSpecialty etc.
Code:
private List serviceLines = new ArrayList(); // Also it’s get/set methods
private List domainSpecialties = new ArrayList();// Also it’s get/set methods.
The various widgets on the screen are bound to various fields of Project object and its child objects.
For example, on page 1, the user selects service lines, saves the data and moves to page 2. The database is updated correctly. The project and service lines are saved.
On page 2, the user selects DomainSpecialties and saves the data. The project is saved correctly, and the DomainSpecialties are saved. However, the problem is - the serviceLines are deleted from the database.
However, the in-memory domain objects Project (and its child objects) contain the correct data.
After the first save, the objects are detached from the Hibernate session and therefore, we tried
Code:
getHibernateTemplate().merge(project);
to merge the detached objects into the persistent object. However this does not work.
The serviceLines, which are the detached objects (after the first save) are deleted from the database (during the second save). The DomainSpecialties, which are the new objects, are inserted into the database.
However, Project (which is the top level object is always updated correctly).
We have a temporary work around, which seems to work when we create a new collection of service lines and copy all the service lines from the old collection into it.
This saves the service lines correctly in all the cases.
Code:
if(project.getServiceLines()!=null){
List objServiceLinesList = new ArrayList();
for(int i=0;i<project.getServiceLines().size();i++){
objServiceLinesList.add(project.getServiceLines().get(i));
}
project.getServiceLines().clear();
project.getServiceLines().addAll(objServiceLinesList);
}
Screen log
First screen - 2 ref data items selected
Mar 26, 2008 5:15:06 PM org.acegisecurity.event.authorization.LoggerListener onApplicationEvent
INFO: Security interception not required for public secure object: FilterInvocation: URL: /flows/k/_c99218BD0-DA42-28E6-EE01-A28D46BE5F88_kA8E1A6F1-6AF6-168B-A784-8634EA04F503
Mar 26, 2008 5:15:06 PM org.acegisecurity.event.authorization.LoggerListener onApplicationEvent
INFO: Security authorized for authenticated principal: org.acegisecurity.providers.UsernamePasswordAuthenticationToken@73151c8b: Username: com.accenture.adsj.credentials.web.security.PersonSecurityDetails@165547d; Password: [PROTECTED]; Authenticated: true; Details: org.acegisecurity.ui.WebAuthenticationDetails@255f8: RemoteIpAddress: 127.0.0.1; SessionId: 28496FE8FA4727C9E2A9B6A7E5B36773; Granted Authorities: ROLE_ADMIN, ROLE_EDITOR; secure object: invocation: method 'updateProjectCredential', arguments [com.accenture.adsj.credentials.domain.ProjectCredential@16eacf1, 1]; target is of class [com.accenture.adsj.credentials.service.ProjectServiceImpl]; configuration attributes: [ACL_PROJECT_CREDENTIAL_WRITE, ROLE_EDITOR]
Mar 26, 2008 5:15:06 PM com.accenture.adsj.credentials.service.ProjectServiceImpl storeProjectCredential
INFO: Saving the project information to the database.
Hibernate:
update
PROJECT
set
clientName=?,
pseudo=?,
name=?,
locationonshore=?,
locationoffshore=?,
geographicUnit=?,
operatingGroup=?,
workgroup=?,
projectManager=?,
techArch=?,
srExec=?,
key_contacts=?,
headline=?,
ext_desc=?,
biz_case=?,
benefits=?,
improvements=?,
approach=?,
subcontractors_res=?,
solutions_res=?,
offshore_res=?,
client_res=?,
consulting_res=?,
totalTechStaff=?,
estimated=?,
fees=?,
client_approver=?,
approval_ok=?,
lcp_approver=?,
client_approved=?,
public=?,
facing_name=?,
contactable=?,
phone=?,
restrictions=?,
special_approv=?,
credentialApprovedByPartner=?,
internalOnly=?,
external=?,
marketing=?,
engagementApprover=?,
engagementSrExec=?,
startDate=?,
completionDate=?,
currentPhase=?,
total_users=?,
other_ui=?,
average=?,
peak=?,
batch_reqs=?,
databaseSize=?,
hi_avail=?,
disaster_recovery=?,
comments=?,
technologyPlatform=?,
technologyPlatformOther=?,
appStylesOther=?,
executionServicesOther=?,
assetsOther=?,
clientConfig=?,
webTierConfig=?,
appTierConfig=?,
dataTierConfig=?,
integrationTierConfig=?,
appServer=?,
contentManagementSystem=?,
databaseServer=?,
erp=?,
integrationServer=?,
operatingSystem=?,
portalServer=?,
security=?,
webServer=?,
contentManagementSystemOther=?,
securityOther=?,
appServerOther=?,
webServerOther=?,
operatingSystemOther=?,
erpOther=?,
databaseServerOther=?,
integrationServerOther=?,
portalServerOther=?,
legacyOther=?,
librariesOther=?,
comment=?,
biToolsOther=?,
monitoringToolsOther=?,
buildToolsOther=?,
developmentToolsOther=?,
presentationServiceToolsOther=?,
appLogicDevelopmentToolsOther=?,
projectManagementToolsOther=?,
distributionServicesToolsOther=?,
dataAccessServiceToolsOther=?,
workflowServiceToolsOther=?,
folderManagementServiceToolsOther=?,
environmentServiceToolsOther=?,
testingToolsOther=?,
versionControlToolsOther=?,
issueTrackingToolsOther=?,
executionArchitectureOther=?,
applicationsOther=?,
openSourceOther=?,
clientExperiencesUrl=?,
status=?,
extMarketingUrl=?,
surveyCreationDate=?,
submitter=?,
lastupdateddate=?
where
id=?
Hibernate:
delete
from
PROJECT_REFDATA
where
PROJECT_ID=?
Hibernate:
delete
from
PROJECT_REFDATA
where
PROJECT_ID=?
Hibernate:
insert
into
PROJECT_REFDATA
(PROJECT_ID, REFDATA_ID)
values
(?, ?)
Hibernate:
insert
into
PROJECT_REFDATA
(PROJECT_ID, REFDATA_ID)
values
(?, ?)
Mar 26, 2008 5:15:06 PM org.acegisecurity.event.authorization.LoggerListener onApplicationEvent
INFO: Security interception not required for public secure object: FilterInvocation: URL: /flows/k/_c99218BD0-DA42-28E6-EE01-A28D46BE5F88_k0329F90B-52E6-8DF7-A796-07128A5CC57D
Next screen - 1 new ref data item selected. All the previous ref data items are deleted.
Mar 26, 2008 5:16:20 PM org.acegisecurity.event.authorization.LoggerListener onApplicationEvent
INFO: Security interception not required for public secure object: FilterInvocation: URL: /flows/k/_c99218BD0-DA42-28E6-EE01-A28D46BE5F88_k14A7DB74-3866-2816-2FBB-8D0E91A56742
Mar 26, 2008 5:16:20 PM org.acegisecurity.event.authorization.LoggerListener onApplicationEvent
INFO: Security authorized for authenticated principal: org.acegisecurity.providers.UsernamePasswordAuthenticationToken@73151c8b: Username: com.accenture.adsj.credentials.web.security.PersonSecurityDetails@165547d; Password: [PROTECTED]; Authenticated: true; Details: org.acegisecurity.ui.WebAuthenticationDetails@255f8: RemoteIpAddress: 127.0.0.1; SessionId: 28496FE8FA4727C9E2A9B6A7E5B36773; Granted Authorities: ROLE_ADMIN, ROLE_EDITOR; secure object: invocation: method 'updateProjectCredential', arguments [com.accenture.adsj.credentials.domain.ProjectCredential@980b32, 4]; target is of class [com.accenture.adsj.credentials.service.ProjectServiceImpl]; configuration attributes: [ACL_PROJECT_CREDENTIAL_WRITE, ROLE_EDITOR]
Mar 26, 2008 5:16:20 PM com.accenture.adsj.credentials.service.ProjectServiceImpl storeProjectCredential
INFO: Saving the project information to the database.
Hibernate:
update
PROJECT
set
clientName=?,
pseudo=?,
name=?,
locationonshore=?,
locationoffshore=?,
geographicUnit=?,
operatingGroup=?,
workgroup=?,
projectManager=?,
techArch=?,
srExec=?,
key_contacts=?,
headline=?,
ext_desc=?,
biz_case=?,
benefits=?,
improvements=?,
approach=?,
subcontractors_res=?,
solutions_res=?,
offshore_res=?,
client_res=?,
consulting_res=?,
totalTechStaff=?,
estimated=?,
fees=?,
client_approver=?,
approval_ok=?,
lcp_approver=?,
client_approved=?,
public=?,
facing_name=?,
contactable=?,
phone=?,
restrictions=?,
special_approv=?,
credentialApprovedByPartner=?,
internalOnly=?,
external=?,
marketing=?,
engagementApprover=?,
engagementSrExec=?,
startDate=?,
completionDate=?,
currentPhase=?,
total_users=?,
other_ui=?,
average=?,
peak=?,
batch_reqs=?,
databaseSize=?,
hi_avail=?,
disaster_recovery=?,
comments=?,
technologyPlatform=?,
technologyPlatformOther=?,
appStylesOther=?,
executionServicesOther=?,
assetsOther=?,
clientConfig=?,
webTierConfig=?,
appTierConfig=?,
dataTierConfig=?,
integrationTierConfig=?,
appServer=?,
contentManagementSystem=?,
databaseServer=?,
erp=?,
integrationServer=?,
operatingSystem=?,
portalServer=?,
security=?,
webServer=?,
contentManagementSystemOther=?,
securityOther=?,
appServerOther=?,
webServerOther=?,
operatingSystemOther=?,
erpOther=?,
databaseServerOther=?,
integrationServerOther=?,
portalServerOther=?,
legacyOther=?,
librariesOther=?,
comment=?,
biToolsOther=?,
monitoringToolsOther=?,
buildToolsOther=?,
developmentToolsOther=?,
presentationServiceToolsOther=?,
appLogicDevelopmentToolsOther=?,
projectManagementToolsOther=?,
distributionServicesToolsOther=?,
dataAccessServiceToolsOther=?,
workflowServiceToolsOther=?,
folderManagementServiceToolsOther=?,
environmentServiceToolsOther=?,
testingToolsOther=?,
versionControlToolsOther=?,
issueTrackingToolsOther=?,
executionArchitectureOther=?,
applicationsOther=?,
openSourceOther=?,
clientExperiencesUrl=?,
status=?,
extMarketingUrl=?,
surveyCreationDate=?,
submitter=?,
lastupdateddate=?
where
id=?
Hibernate:
delete
from
PROJECT_REFDATA
where
PROJECT_ID=?
Hibernate:
insert
into
PROJECT_REFDATA
(PROJECT_ID, REFDATA_ID)
values
(?, ?)
Mar 26, 2008 5:16:20 PM org.acegisecurity.event.authorization.LoggerListener onApplicationEvent
INFO: Security interception not required for public secure object: FilterInvocation: URL: /flows/k/_c99218BD0-DA42-28E6-EE01-A28D46BE5F88_kCAA20C5F-412E-EEA3-DA6B-99AA174D3915
Any ideas on what is the right solution for this issue?