我正在尝试在Spring Data Jpa中进行自我ManyToMany关系,
Terminal.class
package com.sopiyan.travel.model.entity;
import com.fasterxml.jackson.annotation.JsonBackReference;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.io.Serializable;
import java.util.Collection;
/**
* Created by Sopiyan on 31/05/2016.
*/
@Entity
@XmlRootElement
@Table(name = "terminal")
//@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "idTerminal")
public class Terminal implements Serializable, Comparable<Terminal> {
@Id
@Column(name = "id_terminal", nullable = false, unique = true)
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private String idTerminal;
@Column(name = "nama_terminal", nullable = false, unique = true)
private String namaTerminal;
@JoinColumn(name = "id_kota",referencedColumnName = "id_kota", nullable = false)
@ManyToOne(optional = false)
@JsonBackReference
private Kota kota;
@OneToMany(mappedBy = "terminalAsal", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@XmlTransient
@JsonBackReference
private Collection<Rute> listTerminalAsal;
@OneToMany(mappedBy = "terminalTujuan", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@XmlTransient
@JsonBackReference
private Collection<Rute> listTerminalTujuan;
public Collection<Rute> getListTerminalAsal() {
return listTerminalAsal;
}
public void setListTerminalAsal(Collection<Rute> listTerminalAsal) {
this.listTerminalAsal = listTerminalAsal;
}
public Collection<Rute> getListTerminalTujuan() {
return listTerminalTujuan;
}
public void setListTerminalTujuan(Collection<Rute> listTerminalTujuan) {
this.listTerminalTujuan = listTerminalTujuan;
}
public Kota getKota() {
return kota;
}
public void setKota(Kota kota) {
this.kota = kota;
}
public String getIdTerminal() {
return idTerminal;
}
public void setIdTerminal(String idTerminal) {
this.idTerminal = idTerminal;
}
public String getNamaTerminal() {
return namaTerminal;
}
public void setNamaTerminal(String namaTerminal) {
this.namaTerminal = namaTerminal;
}
@Override
public int compareTo(Terminal terminal) {
return this.idTerminal.compareTo(terminal.getIdTerminal());
}
}
Rute.class
package com.sopiyan.travel.model.entity;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import java.io.Serializable;
import java.util.Collection;
/**
* Created by Sopiyan on 31/05/2016.
*/
@Entity
@XmlRootElement
@Table(name = "rute")
public class Rute implements Serializable, Comparable<Rute>{
@Id
@Column(name = "id_rute", nullable = false, unique = true)
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private String idRute;
@JoinColumn(name = "id_terminal_asal", referencedColumnName = "id_terminal")
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonManagedReference
private Terminal terminalAsal;
@JoinColumn(name = "id_terminal_tujuan", referencedColumnName = "id_terminal")
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JsonManagedReference
private Terminal terminalTujuan;
@Column(name = "harga", nullable = false)
private double harga;
@OneToMany(mappedBy = "rute")
@XmlTransient
private Collection<Tiket> listTiket;
public Collection<Tiket> getListTiket() {
return listTiket;
}
public void setListTiket(Collection<Tiket> listTiket) {
this.listTiket = listTiket;
}
public String getIdRute() {
return idRute;
}
public void setIdRute(String idRute) {
this.idRute = idRute;
}
public Terminal getTerminalAsal() {
return terminalAsal;
}
public void setTerminalAsal(Terminal terminalAsal) {
this.terminalAsal = terminalAsal;
}
public Terminal getTerminalTujuan() {
return terminalTujuan;
}
public void setTerminalTujuan(Terminal terminalTujuan) {
this.terminalTujuan = terminalTujuan;
}
public double getHarga() {
return harga;
}
public void setHarga(double harga) {
this.harga = harga;
}
@Override
public int compareTo(Rute rute) {
return this.idRute.compareTo(rute.getIdRute());
}
}
我正在尝试保存Rute Entity,但我收到了错误。问题在哪里?
错误:
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist: com.sopiyan.travel.model.entity.Terminal; nested exception is org.hibernate.PersistentObjectException: detached entity passed to persist: com.sopiyan.travel.model.entity.Terminal
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:491)
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.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy101.save(Unknown Source)
at com.sopiyan.travel.UserTest.simpan(UserTest.java:62)
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:483)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
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:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.sopiyan.travel.model.entity.Terminal
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:768)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:761)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener$1.cascade(JpaPersistEventListener.java:80)
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316)
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:104)
at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:414)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:252)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:182)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
at org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67)
at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:778)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:751)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:756)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146)
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:483)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
at com.sun.proxy.$Proxy91.persist(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:506)
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:483)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:503)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:488)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
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:281)
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)
... 40 more