Relation ManyToOne,javax.persistence.EntityExistsException:具有相同标识符值的另一个对象已与会话关联

时间:2012-09-14 00:58:30

标签: jpa spring-data-jpa

我花了很多时间搜索错误,但我无法解决这个问题。 我使用Spring JPA与Hibernate和Postgre。 我有两个实体Location和Ap:

    CREATE TABLE ap
(
  id serial NOT NULL,
  ssid text NOT NULL,
  bssid text NOT NULL,
  capabilities text,
  CONSTRAINT ap_pkey PRIMARY KEY (id )
)
CREATE TABLE location2
(
  latitude double precision NOT NULL,
  longitude double precision NOT NULL,
  power integer NOT NULL,
  ap_id integer,
  id serial NOT NULL,
  CONSTRAINT location2_pkey PRIMARY KEY (id ),
  CONSTRAINT location2_ap_id_fkey FOREIGN KEY (ap_id)
      REFERENCES ap (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

AP:

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "ap")
public class Ap implements Serializable {
    private Long id;
    private String ssid;
    private String bssid;
    private String capabilities;
    private Set<Location> locations = new HashSet<Location>();

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @OneToMany(mappedBy = "ap", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    public Set<Location> getLocations() {
        return locations;
    }

    public void setLocations(Set<Location> locations) {
        this.locations = locations;
    }

    @Column
    public String getSsid() {
        return ssid;
    }

    public void setSsid(String ssid) {
        this.ssid = ssid;
    }

    @Column
    public String getBssid() {
        return bssid;
    }

    public void setBssid(String bssid) {
        this.bssid = bssid;
    }

    @Column
    public String getCapabilities() {
        return capabilities;
    }

    public void setCapabilities(String capabilities) {
        this.capabilities = capabilities;
    }

    public void addLocation(Location location) {
        location.setAp(this);
        getLocations().add(location);
    }

    public void removeLocation(Location location) {
        getLocations().remove(location);
    }

    public Ap() {
        super();
    }

    public Ap(String ssid, String bssid, String capabilities) {
        this.ssid = ssid;
        this.bssid = bssid;
        this.capabilities = capabilities;
    }

}

LOCATION2

@Entity
@Table(name = "location2")

public class Location implements Serializable {

    private Long id;
    private double latitude;
    private double longitude;
    private int power;
    private Ap ap;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @ManyToOne
    @JoinColumn(name = "ap_id")
    public Ap getAp() {
        return ap;
    }

    public void setAp(Ap ap) {
        this.ap = ap;
    }

    @Column
    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    @Column
    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    @Column
    public int getPower() {
        return power;
    }

    public void setPower(int power) {
        this.power = power;
    }

    public Location(double latitude, double longitude, int power) {
        super();
        this.latitude = latitude;
        this.longitude = longitude;
        this.power = power;
    }

    public Location() {
        super();
    }

当我向Ap添加一个位置时,它可以工作,但是当Ap有两个或更多位置时,我无法保存Ap实体。

ApService service=context.getBean("ApService", ApService.class);
    Ap ap=new Ap("test_ssid2", "test_bssid2", "test_capabilities2");
    ap.addLocation(new Location(9.121, 12.9, 12));
    ap.addLocation(new Location(9.122, 12.9, 12));
    service.save(ap);

ApService:

 public Ap save(Ap ap) {
        return apRepository.save(ap);
    }

案例错误:

Exception in thread "main" org.springframework.dao.DataIntegrityViolationException: a different object with the same identifier value was already associated with the session: [com.kulig.ap.domain.Location#9]; nested exception is javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [com.kulig.ap.domain.Location#9]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:318)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:106)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:403)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:58)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:163)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.data.jpa.repository.support.LockModeRepositoryPostProcessor$LockModePopulatingMethodIntercceptor.invoke(LockModeRepositoryPostProcessor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy24.save(Unknown Source)
at com.kulig.ap.service.jpa.ApServiceImpl.save(ApServiceImpl.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy29.save(Unknown Source)
at com.kulig.ap.Test.main(Test.java:24)
Caused by: javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [com.kulig.ap.domain.Location#9]
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1359)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1315)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1321)
    at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:843)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
    at $Proxy19.persist(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:341)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:334)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:319)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:155)
    ... 22 more

我还尝试了使用merge和persist方法的EntityManager,这也给出了同样的错误。 请帮忙。

0 个答案:

没有答案