2012-09-14 16 views
6

Pasé mucho tiempo buscando el error y no puedo resolverlo. Uso Spring JPA con Hibernate y Postgre. Tengo dos entidades Ubicación y AP:Relación ManyToOne, javax.persistence.EntityExistsException: un objeto diferente con el mismo valor de identificador ya estaba asociado con la sesión

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(); 
    } 

Cuando agrego un lugar a Ap funciona, pero cuando Ap tiene dos o más Ubicación No puedo guardar la entidad 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); 
    } 

It casos de error:

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 

También probé con EntityManager de combinación y persisten los métodos y esto da el mismo error. Por favor ayuda.

Respuesta

1

En Ubicación intenta cambiar

@Id 
@GeneratedValue(strategy = GenerationType.IDENTITY) 
@Column(name = "id") 

a

@Id 
@GeneratedValue(generator="LOCATION_SEQ_GEN",strategy=GenerationType.SEQUENCE) 
@SequenceGenerator(sequenceName="location_sequence_name",name="LOCATION_SEQ_GEN",allocationSize=1) 

He oído que es una mala práctica allocationSize=1 pero por lo demás hay problemas con la secuencia. Puede leer más Hibernate use of PostgreSQL sequence does not affect sequence table

+1

El allocationSize describe la cantidad de números de secuencia que se deben extraer por obtención de DB. Esto es sobre el rendimiento. Si se establece en "10", el contenedor incrementará la secuencia en 10 en el DB y mantendrá N-10 en la memoria. Cuando se necesita un valor, agota primero el grupo en memoria antes de volver a recuperarlo del DB. Esto potencialmente 'quema' números de secuencia no utilizados para el beneficio de un mejor rendimiento. Sospecho que el gestor de secuencia de Hibernate (que no tiene nada que ver con la implementación de DB) no está manteniendo el seguimiento adecuado del grupo de secuencias en memoria. –

Cuestiones relacionadas