当前位置: 首页 > 知识库问答 >
问题:

Hibernate@ManyTomany单向关系[重复]

印辉
2023-03-14

我想在account(您可以将其视为Student)实体和classum实体之间实现一个@ManyTomany单向的。很简单,一个教室可以有很多学生,而学生可以有很多教室。我希望它是单向的,因为我希望班级只知道它包含什么学生,学生不必知道他们有什么班级。这就是我目前所拥有的:
ClassRoom.java

@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

下面是StackTrace:

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

共有1个答案

仲俊豪
2023-03-14

在级联子级时,如果级联的实体没有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);
 类似资料:
  • 我有两个类:< code>User和< code>UserProfile。 用户类别: 用户配置文件类: 当我使用此代码时,我在具有多对多关系的表用户配置文件中获得重复的实体。我使用 函数来保存对象。我做错了什么? 然后我删除 cascadeType,出现错误:对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例。 Hibernate日志:

  • 我正在尝试链接mysql表(role、user、user_role)。 UserModel实体包含字段“roles”。 当我保存用户时,表'roles'中会自动创建新行。如何取消重复角色?

  • 问题内容: 我不确定如何描述这个问题,所以我认为举个例子是问我问题的最好方法: 我有两个表具有多对多关系: 驾驶执照<-> LicenceClass LicenceClass是“汽车”,“摩托车”和“中型刚性”之类的东西。 使用Hibernate Criteria,如何找到同时具有“汽车”和“摩托车” LicenceClasses的所有许可证? 2008年12月11日更新我发现可以使用自定义Res

  • 问题内容: 我下面有两个… 我想更新的,有时也用下面的方法有时… 方法#1 方法#2 第一种方法可以正常工作,但第二种则不能。但是,当我将“ 从” 移至“ 第二”方法时,效果很好,而不是第一个。 问题答案: 问题是一个问题。 假设它是的子类,那么您的问题是关系中只有一方是拥有实体。将使得实体所属的实体,因此仅改变该实体被持久化。这意味着,你必须更新在这两种情况下的实体。如果您有一个“ a”的组列表

  • 在一个项目中,我有以下实体:具有连接到关键字的模板部分的模板。这两种关系都是。一些代码: 然后,我尝试使用给定ID查找与某个模板相关的关键字。我使用使用此谓词执行此操作: 由于某些原因,谓词处理得根本不好。尝试调用方法时出现此错误: 组织.hibernate.hql.internal.ast.QuerySyntax 异常: 模板实体部分目录未映射 [选择关键字身份\nfrom mypackage.

  • 我很难找到如何在Spring中从@manytomany关系中检索数据。我遇到了无限递归问题,并尝试了一些解决方案,比如使用@JSONIgnoreProperties,但都没有成功。 一个用户可以有多个组,一个组可以有多个用户。我可以将用户添加到组中,但是当涉及到检索与用户关联的所有组时,我会从无限递归中得到堆栈溢出。 理想情况下,我希望能够发送带有用户ID的get请求,然后检索与该用户关联的所有G