JPA Update实体抛出错误

时间:2015-03-17 21:49:15

标签: java hibernate jpa

我有一个名为Student的实体,它有一个StudentAccount。关系是1:1。当我更新学生时,它不会更新相关的StudentAccount详细信息,而是创建一个新的StudentAccount并抛出:

  

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '4' for key 'UK_tr1t4oo8ivgiur0xy63odvvfy'

因为已经有具有特定ID的学生的StudentAccount。 我做错了什么?

@Entity
@Table
public class StudentAccount implements DomainModel {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer idstudentaccount;
    @OneToOne(optional = false)
    @JoinColumn(name = "idstudent")
    private Student student;
    private String username;
    private String password;
    //getters and setters
}
    @Entity
@Table(name = "student")
public class Student implements DomainModel {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer idStudent;
    private String firstname;
    private String lastname;
    @OneToOne(mappedBy = "student", cascade = CascadeType.ALL, targetEntity=StudentAccount.class)
    private StudentAccount studentAccount;
    //getters and setters
}


 public class GenericDAOImpl<T extends DomainModel> implements GenericDAO<T> {

    private Class<T> type;
    protected EntityManager entityManager;

    public GenericDAOImpl(Class<T> type) {
        this.type = type;
    }

    @Transactional
    public T getObjectById(Integer id) {
        if (id == null) {
            return null;
        } else {
            return getEntityManager().find(type, id);
        }
    }

    @SuppressWarnings("unchecked")
    @Transactional
    public List<T> getAll() {
        return getEntityManager().createQuery(
                "select o from " + type.getName() + " o ").getResultList();

    }
    @Transactional
    public void save(T object) {
        entityManager.persist(object);
    }

    @Transactional
    public T updateObject(T object) {
        return getEntityManager().merge(object);
    }
    @Transactional
    public void delete(T object) {
        entityManager.remove(object);
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    @PersistenceContext(unitName="repository")
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
}

整个堆栈跟踪:

com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '4' for key 'UK_tr1t4oo8ivgiur0xy63odvvfy'
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
com.mysql.jdbc.Util.getInstance(Util.java:381)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2643)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2362)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2280)
com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2265)
org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)
org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3032)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3558)
org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:98)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:490)
org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:195)
org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:179)
org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:214)
org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:324)
org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:288)
org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:194)
org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
org.hibernate.jpa.event.internal.core.JpaMergeEventListener.saveWithGeneratedId(JpaMergeEventListener.java:73)
org.hibernate.event.internal.DefaultMergeEventListener.saveTransientEntity(DefaultMergeEventListener.java:271)
org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:251)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:189)
org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:886)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:868)
org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:277)
org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:350)
org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:293)
org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:161)
org.hibernate.engine.internal.Cascade.cascade(Cascade.java:118)
org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:474)
org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:343)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186)
org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:291)
com.sun.proxy.$Proxy32.merge(Unknown Source)
com.af.dao.impl.GenericDAOImpl.updateObject(GenericDAOImpl.java:54)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
com.sun.proxy.$Proxy33.updateObject(Unknown Source)
com.af.service.impl.StudentServiceImpl.updateStudent(StudentServiceImpl.java:50)
com.af.controller.StudentController.editProfilePOST(StudentController.java:91)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

1 个答案:

答案 0 :(得分:0)

看起来同一个学生(id = 4)不止一次与StudentAccount相关联,反之亦然。根据您的注释判断,您只需要1-1映射,因此检查您的数据库以查看是否存在此重复,我敢打赌它会。删除副本后,应解决问题。