2017-08-13 100 views
1

我想在Account(可以把它當作學生)實體和Classroom實體之間實現一個@ManyToMany單向。很簡單,一間教室可以有很多學生,而學生可以有很多教室。我希望它是單向的,因爲我希望班級知道它只包含學生,學生不必知道他們有什麼班級。這所以到目前爲止我有:
Classroom.javaHibernate @ManyToMany單向關係

@Entity(name = "Classroom") 
@Table(name = "classroom") 
public class Classroom extends BaseEntity 
{ 
    @Column(name = "classroom_id", nullable = false, length = 20, unique = true) 
    private String classroomId; 
    @Column(name = "module_code", nullable = false, length = 50, unique = true) 
    private String moduleCode; 
    @Column(name = "classroom_name", nullable = false, length = 100, unique = true) 
    private String classroomName; 
    @Column(name = "password", nullable = false, length = 45) 
    private String password; 
    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinTable(name = "classroom_student", 
      joinColumns = @JoinColumn(name = "classroom_id"), inverseJoinColumns = @JoinColumn(name = "account_id")) 
    private Set<Account> students; 
} 

Account.java

@Entity(name = "Account") 
@Table(name = "account") 
public class Account extends BaseEntity 
{ 
    @Column(name = "email", nullable = false, length = 50, unique = true) 
    private String email; 
    @Column(name = "username", nullable = false, length = 20, unique = true) 
    private String username; 
    @Column(name = "password", nullable = false, length = 45) 
    private String password; 
    @Column(name = "sid", nullable = false, length = 20, unique = true) 
    private String sid; 
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
    @JoinColumn(name = "profile_id", nullable = false) 
    private Profile profile; 
    @Column(name = "acc_type", nullable = false, length = 1) 
    private char accType; 
} 

,我保存它通過下面的代碼(與Spring JPA):

classroom.setClassroomId("ABCD123321345"); 
Set<Account> account = new HashSet<>(); 
account.add(accountService.findByUsername("abc")); 
account.add(accountService.findByUsername("def")); 
System.out.println("Size: " + account.size()); //result is 2 
classroom.setStudents(account); 
classroomService.insertOrUpdate(classroom); 

但我得到了以下錯誤:

PersistentObjectException: detached entity passed to persist: com.peter.uass.model.Account 

這裏是堆棧跟蹤:

javax.faces.FacesException: #{classroomBean.createClassroom()}: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.peter.uass.model.Account; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.peter.uass.model.Account 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) 
    at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790) 
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282) 
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167) 
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) 
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) 
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) 
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132) 
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111) 
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) 
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536) 
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) 
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591) 
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: javax.faces.el.EvaluationException: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.peter.uass.model.Account; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.peter.uass.model.Account 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101) 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
    ... 35 more 
Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.peter.uass.model.Account; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.peter.uass.model.Account 
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:299) 
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:488) 
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59) 
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) 
    at com.sun.proxy.$Proxy1321.save(Unknown Source) 
    at com.peter.uass.service.BaseServiceImpl.insertOrUpdate(BaseServiceImpl.java:27) 
    at com.peter.uass.service.BaseServiceImpl$$FastClassBySpringCGLIB$$dbade7b8.invoke(<generated>) 
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) 
    at com.peter.uass.service.ClassroomService$$EnhancerBySpringCGLIB$$fd4dbc5d.insertOrUpdate(<generated>) 
    at com.peter.uass.bean.ClassroomBean.createClassroom(ClassroomBean.java:61) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at javax.el.ELUtil.invokeMethod(ELUtil.java:332) 
    at javax.el.BeanELResolver.invoke(BeanELResolver.java:537) 
    at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:256) 
    at com.sun.el.parser.AstValue.invoke(AstValue.java:283) 
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304) 
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87) 
    ... 36 more 
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.peter.uass.model.Account 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:139) 
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:797) 
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:790) 
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:97) 
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:352) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:295) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) 
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:381) 
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:321) 
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:298) 
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161) 
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118) 
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:460) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:294) 
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194) 
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125) 
    at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:84) 
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:206) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:149) 
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:75) 
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:807) 
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:780) 
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:785) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1181) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) 
    at com.sun.proxy.$Proxy1315.persist(Unknown Source) 
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:508) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:504) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:489) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) 
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) 
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) 
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) 
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) 
    ... 68 more 

對此有何想法?我實施的關係有什麼問題嗎?

+0

可以共享此帳戶服務的代碼? –

+0

@AmerQarabsa沒有什麼帳戶服務,有什麼不AccountService的只是調用春庫保存的實體。 – Newbie

+0

這裏檢查後,https://stackoverflow.com/questions/19610608/hibernate-exception-detached-entity-passed-to-persist – Imran

回答

1

在層疊子級上,如果級聯實體沒有ID,它將在層疊中指定操作時級聯(在您的情況下級聯所有操作),但是如果實體的ID有意義該實體已經存在,並且由於該實體未被管理,它將被視爲分離的實體。

服務會話將被關閉,以便實體將在持久化上下文不再的號召後,使用你的資料庫,而不是從服務得到它讓你的實體。

Autowired 
private AccountDao accountDao;//AccoutDao is the jpa repository for the account 



classroom.setClassroomId("ABCD123321345"); 
Set<Account> account = new HashSet<>(); 
account.add(accountDao.findByUsername("abc")); 
account.add(accountDao.findByUsername("def")); 
System.out.println("Size: " + account.size()); //result is 2 
classroom.setStudents(account); 
classroomService.insertOrUpdate(classroom); 
+0

如果刪除CascadeType的,我得到了'MySQLNonTransientConnectionException:沒有允許發言收盤後操作。 '錯誤 – Newbie

+0

解決的辦法是不要刪除級聯,是你將有你參照堅持實體的臨時實體(不保留)另外一個問題,用你的資料庫,而不是直接的服務,所以你可以在你的檢索對象同一屆會議 –