2012-07-24 68 views
0

嗨,我是新的休眠。插入自映射實體作爲休眠中的包鑰匙

我有一個場景等有定期服務和捆綁服務(定期服務組合)

我創建像

CREATE TABLE `dealer_service` (
`id_service` INT(11) NOT NULL AUTO_INCREMENT, 
`service_name` VARCHAR(45) NULL DEFAULT NULL COMMENT , 
`short_desc` VARCHAR(45) NULL DEFAULT NULL COMMENT , 
`full_desc` VARCHAR(500) NULL DEFAULT NULL COMMENT , 
`cost` FLOAT NULL DEFAULT NULL COMMENT, 
`currency` VARCHAR(45) NULL DEFAULT NULL COMMENT , 
`tax` FLOAT NULL DEFAULT NULL COMMENT , 
`discounts` FLOAT NULL DEFAULT NULL COMMENT , 

PRIMARY KEY (`id_service`), 
) 
COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

映射定期服務和捆綁服務之間

CREATE TABLE `service_to_services` (
`service_id_main` INT(11) NOT NULL, 
`service_id_sub` INT(11) NOT NULL, 
PRIMARY KEY (`service_id_main`, `service_id_sub`) 
) 
COMMENT='maping table between service to service if service is bundle' 
    COLLATE='utf8_general_ci' 
ENGINE=InnoDB; 

休眠類是

import stati c javax.persistence.GenerationType.IDENTITY;

@Entity 
@Table(name = "dealer_service") 
public class DealerService implements java.io.Serializable { 

private Integer     idService; 
private String     serviceName; 
private String     shortDesc; 
private String     fullDesc; 
private String     offeredBy; 
private String     terms; 
private String     discriminator; 
. 
    . 
    . 

private Set<DealerService>  subServices; 

// getter和setter方法

@ManyToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, 
     CascadeType.ALL }, fetch = FetchType.EAGER) 
@JoinTable(name = "service_to_services", 
      joinColumns = { @JoinColumn(name = "service_id_main") }, 
      inverseJoinColumns = { @JoinColumn(name = "service_id_sub") }) 
public Set<DealerService> getSubServices() { 
    return subServices; 
} 

public void setSubServices(Set<DealerService> subServices) { 
    this.subServices = subServices; 
} 

}

現在的問題是我有一個更表中調用服務事件 的POJO類是這樣的..

@Entity 
@Table(na me = "service_incident") 
public class ServiceIncident implements java.io.Serializable { 


private Set<DealerService>selectedServices= new HashSet<DealerService>(0); 


@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) 
@JoinTable(name = "work_list", 
      joinColumns = { @JoinColumn(name = "service_incident_id") }, 
      inverseJoinColumns = { @JoinColumn(name = "dealer_service_id") }) 
public Set<DealerService> getSelectedServices() { 
    return selectedServices; 
} 

public void setSelectedServices(Set<DealerService> selectedServices) { 
    this.selectedServices = selectedServices; 
}          0); 
} 

嘗試在服務中插入選定的服務事件是通過異常 像

org.springframework.dao.DuplicateKeyException: a different object with the same identifier value was already associated with the session: [cc.carcloud.domain.DealerService#2]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [cc.carcloud.domain.DealerService#2] 
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:662) 
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412) 
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411) 
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374) 
at org.springframework.orm.hibernate3.HibernateTemplate.save(HibernateTemplate.java:683) 
at cc.carcloud.dao.GenericDaoImpl.save(GenericDaoImpl.java:46) 
at cc.carcloud.serviceimpl.ServiceIncidentServiceImpl.add(ServiceIncidentServiceImpl.java:47) 
at cc.carcloud.wscontroller.ServiceIncidentWSController.addServiceIncident(ServiceIncidentWSController.java:92) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:322) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116) 
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
at org.springframework.security.web.authentication.www.DigestAuthenticationFilter.doFilter(DigestAuthenticationFilter.java:209) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) 
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:184) 
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:155) 
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) 
at java.lang.Thread.run(Unknown Source) 
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [cc.carcloud.domain.DealerService#2] 
at org.hibernate.engine.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:590) 
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284) 
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:223) 
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:89) 
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) 
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507) 
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499) 
at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:218) 
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268) 
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216) 
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169) 
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296) 
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242) 
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219) 
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169) 
at org.hibernate.engine.Cascade.cascade(Cascade.java:130) 
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:456) 
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:334) 
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:181) 
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:107) 
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187) 
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33) 
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172) 
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27) 
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70) 
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535) 
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523) 
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519) 
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:686) 
at org.springframework.orm.hibernate3.HibernateTemplate$12.doInHibernate(HibernateTemplate.java:1) 
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:406) 
... 53 more 

任何一個可以請幫助我哪裏錯了..

在此先感謝。

回答

1

消息異常說明了問題所在。您正試圖撥打save(),並因此附加到會話,一個分離的對象。但會話已包含具有相同ID的附加對象。

它可以像下面這樣的情況發生:

DealerService detachedDealerService = new DealerService(); 
detachedDealerService.setId(2); 

DealerService attachedDealerService = session.get(DealerService.class, 2); 
session.save(detachedDealerService); 
// exception: the dealer service with ID 2 is already in the session 

需要注意的是,如果是自動生成的ID的,已經有一個ID的對象上調用save()是錯誤本身。 save()用於創建新的持久對象。