2012-12-07 46 views
2

我有一个我不知道如何解决的轻微问题。请问你能帮帮我吗? 当我试图坚持实体,我得到一个异常:具有相同标识符值的不同对象在尝试坚持实体时已与会话相关联

12:47:39,398 ERROR [org.black.dmitriy.entityHome.ScheduleHome] (http--127.0.0.1-8080-1) javax.persistence.EntityExistsException: a different object with the same identifier value was already associated with the session: [org.black.dmitriy.entity.Schedule#1] 
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1333) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final] 
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1289) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final] 
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1295) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final] 
at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:859) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final] 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_04] 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_04] 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_04] 
at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_04] 
at org.jboss.seam.persistence.EntityManagerInvocationHandler.invoke(EntityManagerInvocationHandler.java:46) [jboss-seam.jar:2.3.0.Final] 
at $Proxy81.persist(Unknown Source) at org.jboss.seam.framework.EntityHome.persist(EntityHome.java:84) [jboss-seam.jar:2.3.0.Final] 
at org.black.dmitriy.entityHome.ConversationHome.tryPersist(ConversationHome.java:147) [ejb.jar:] 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_04] 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_04] 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_04] 
at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_04] 
at org.jboss.seam.util.Reflections.invoke(Reflections.java:22) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:65) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:97) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.util.Work.workInTransaction(Work.java:61) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:186) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:104) [jboss-seam.jar:2.3.0.Final] 
at org.black.dmitriy.entityHome.ScheduleHome_$$_javassist_seam_8.tryPersist(ScheduleHome_$$_javassist_seam_8.java) [ejb.jar:] 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_04] 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_04] 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_04] 
at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_04] 
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335) [jboss-el-1.0_02.CR6.jar:1.0_02.CR6] 
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348) [jboss-el-1.0_02.CR6.jar:1.0_02.CR6] 
at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58) [jboss-el-1.0_02.CR6.jar:1.0_02.CR6] 
at org.jboss.el.parser.AstValue.invoke(AstValue.java:96) [jboss-el-1.0_02.CR6.jar:1.0_02.CR6] 
at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276) [jboss-el-1.0_02.CR6.jar:1.0_02.CR6] 
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) [jsf-impl-2.1.7-jbossorg-2.jar:] 
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) [jsf-impl-2.1.7-jbossorg-2.jar:] 
at javax.faces.component.UICommand.broadcast(UICommand.java:315) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) [jsf-impl-2.1.7-jbossorg-2.jar:] 
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:] 
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:] 
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) [jboss-seam.jar:2.3.0.Final] 
at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) [jboss-seam.jar:2.3.0.Final] 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:397) [jbossweb-7.0.13.Final.jar:] 
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final] 
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final] 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:] 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:] 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:] 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:] 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:] 
at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_04] 

我用缝2.3,冬眠。我在import.sql文件中有一条插入语句:

INSERT INTO Schedules (id, name, dayCount, lessonCount, firstTermSize, secondTermSize, subgroupSize) VALUES(1, '2012/2013', 5, 8, 9, 9, 18) 

它将一个enity插入表计划。

然后,我创建使用EntityHome

@Name("scheduleHome") 
@Scope(ScopeType.CONVERSATION) 
public class ScheduleHome extends ConversationHome<Schedule> { 
    private static final long serialVersionUID = 1L; 

    public ScheduleHome() { 
    } 

    @Override 
    protected boolean isUnique() { 
     Schedule schedule = getInstance(); 
     Schedule foundSchedule = ScheduleDAO.instance().getByName(schedule.getName()); 

     if ((foundSchedule != null) && (!foundSchedule.equals(schedule))) { 
      showExistsErrorMessage(getInstance().getName()); 
      return false; 
     } 

     return true; 
    } 

    @Override 
    protected Schedule createInstance() { 
     return new Schedule(); 
    } 

    @Override 
    public String getEditOutcome() { 
     return "scheduleEdit"; 
    } 

    @Override 
    protected void prepareEntityForSaving() { 

    } 
} 

和超

public abstract class ConversationHome<T> extends EntityHome<T> { 
    private static final long serialVersionUID = 1L; 
    private String parentView; 

    public boolean isParentViewExists() { 
     return parentView != null && parentView.length() > 0; 
    } 

    public void setParentView(String parentView) { 
     this.parentView = parentView; 
    } 

    public String getParentView() { 
     return parentView; 
    } 

    public abstract String getEditOutcome(); 

    protected abstract void prepareEntityForSaving(); 

    protected abstract boolean isUnique(); 

    @Override 
    @Create 
    public void create() { 
     create(false); 
    } 

    protected void create(boolean createNestedConversation) { 
     Conversation conversation = Conversation.instance(); 
     if (!createNestedConversation && conversation.isLongRunning()) { 
      getLog().debug("conversation already started, nested will not create(isLongRunning = #0, isNested = #1)", conversation.isLongRunning(), conversation.isNested()); 
     } else { 
      conversation.begin(false, conversation.isLongRunning()); 
      conversation.changeFlushMode(FlushModeType.MANUAL); 
      getLog().debug("create(isLongRunning = #0, isNested = #1, id = #2)", conversation.isLongRunning(), conversation.isNested(), conversation.getId()); 
     } 
     super.create(); 
    } 

    private boolean init(Long id) { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     setParentView(Pages.getViewId(context)); 

     if (id != null) { 
      setId(id); 
      try { 
       getInstance(); 
       getLog().debug("instance initialized #0", getInstance()); 
      } catch (EntityNotFoundException e) { 
       getLog().error(e); 
       return false; 
      } 
     } 
     return true; 
    } 

    public String startEdit(Long id) { 
     getLog().debug("start editing #0", id); 
     if (init(id)) { 
      return getEditOutcome(); 
     } else { 
      return cancel(); 
     } 
    } 

    public String cancel() { 
     if (isManaged()) { 
      getEntityManager().refresh(getInstance()); 
     } 
     return returnToParent(); 
    } 

    @End 
    protected String returnToParent() { 
     if (isParentViewExists()) { 
       Conversation conversation = Conversation.instance(); 
       getLog().debug("end conversation(id = #0, isLongRunning = #1, isNested = #2)", 
         conversation.getId(), conversation.isLongRunning(), conversation.isNested()); 
       conversation.end(true); 
       return getParentView(); 
      } else { 
       clearInstance(); 
       return null; 
      } 
    } 

    public String tryPersist() { 
     if (isUnique()) { 
      try { 
       prepareEntityForSaving(); 

       String outcome = persist(); 
       if (!"failed".equals(outcome)) { 
        return returnToParent(); 
       } 
      } catch (Exception e) { 
       getLog().error(getInstance(), e); 
       showSaveErrorMessage(e); 
      } 
     } 
     return "failed"; 
    } 
} 

新的时间表实体掷网页,当我试图坚持它,我得到这个例外。和网页上的消息

与消息保存错误:用相同的标识符值不同的物体已经与所述会话相关联:[org.black.dmitriy.entity.Schedule#1]

它接缝该休眠将id属性设置为1,但我已经拥有id = 1的实体,因为我手动创建了它,导致import.sql。

这是我的计划实体:

import java.util.ArrayList; 
import java.util.List; 

import javax.persistence.CascadeType; 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 
import javax.validation.constraints.NotNull; 

@Entity 
@Table(name = "Schedules") 
public class Schedule { 

    @Id 
    @GeneratedValue 
    @Column(name = "id", nullable = false) 
    private Long id; 

    @NotNull 
    @Column(name = "name", nullable = false, length = 40) 
    private String name; 

    @Column(name = "dayCount") 
    private int dayCount = 5; 

    @Column(name = "lessonCount") 
    private int lessonCount = 8; 

    @Column(name = "firstTermSize") 
    private int firstTermSize = 9; 

    @Column(name = "secondTermSize") 
    private int secondTermSize = 9; 

    @Column(name = "subgroupSize") 
    private int subgroupSize = 18; 

    @OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL, targetEntity = Faculty.class) 
    private List<Faculty> faculties = new ArrayList<>(); 

    @OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL, targetEntity = Building.class) 
    private List<Building> buildings = new ArrayList<>(); 

    public Schedule() { 

    } 

    public Long getId() { 
     return id; 
    } 

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

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public int getDayCount() { 
     return dayCount; 
    } 

    public void setDayCount(int dayCount) { 
     this.dayCount = dayCount; 
    } 

    public int getLessonCount() { 
     return lessonCount; 
    } 

    public void setLessonCount(int lessonCount) { 
     this.lessonCount = lessonCount; 
    } 

    public int getFirstTermSize() { 
     return firstTermSize; 
    } 

    public void setFirstTermSize(int firstTermSize) { 
     this.firstTermSize = firstTermSize; 
    } 

    public int getSecondTermSize() { 
     return secondTermSize; 
    } 

    public void setSecondTermSize(int secondTermSize) { 
     this.secondTermSize = secondTermSize; 
    } 

    public int getSubgroupSize() { 
     return subgroupSize; 
    } 

    public void setSubgroupSize(int subgroupSize) { 
     this.subgroupSize = subgroupSize; 
    } 

    public List<Faculty> getFaculties() { 
     return faculties; 
    } 

    public void setFaculties(List<Faculty> faculties) { 
     this.faculties = faculties; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((id == null) ? 0 : id.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (!(obj instanceof Schedule)) { 
      return false; 
     } 
     Schedule other = (Schedule) obj; 
     if (id == null) { 
      if (other.id != null) { 
       return false; 
      } 
     } else if (!id.equals(other.id)) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return this.name; 
    } 
} 

正如你可以看到有关于id属性@GeneratedValue注解,所以我认为应该冬眠生成自己的ID和休眠应该知道,有实体数据库id = 1,并在新实体= 2中设置ID。但Hibernate将新实体中的ID设置为1. 您能请我吗?

回答

11

问题是休眠如何产生的id的,它从1开始。当它指定1时一个对象在保存到数据库之前,它会在数据库中看到一个具有相同ID的行,并导致异常。这个问题的简单和自然的解决方案是简单地限制休眠,以便它不能将1作为id分配给关联类的任何对象(在你的情况下)。

解决方案对于MySQL:

如果你正在使用MySQL,您可以手动创建表,并设置自动递增,如:

CREATE TABLE IF NOT EXISTS `testTable` (
     `id` number(11) NOT NULL AUTO_INCREMENT, 
     ..., 
     ..., 
     ..., 
     PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=2; //assigning id by hibernate, will start from 2. 

而在你的领域类,你可以有标识标注的像波纹管:

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 
@Column(name = "ID") 
public long getId() { 
    .... 
} 

GenerationType.AUTO默认情况下在mySql中使用自动增量。并在设置AUTO_INCREMENT=2后,hibernate将开始从2分配ID(因此跳过1)。

解决方案甲骨文:

用于Oracle的同样的事情,可如果限制使用休眠“序列”来完成,而您将作为你的愿望的初始点。您可以创建一个序列通过12和增量开始像波纹管:

create sequence idSequence 
     start with 2 
     increment by 1 
     maxvalue 9999999999999; 

而且你可以指定你的序列被用来生成ID域类的物体的像波纹管:

@Id 
@SequenceGenerator(name = "idGeneratorSeq", sequenceName = "idSequence") 
@GeneratedValue(strategy = GenerationType.AUTO, generator = "idGeneratorSeq") 
@Column(name = "ID") 
public long getId() { 
    .... 
} 

而且你的问题很难解决。

+0

谢谢。你知道为什么generateValue这样表现吗?当我在桌面应用程序中做同样的事情时,没有任何问题。我通过import.sql添加了实体,并且Hibernate生成了正确的ID。 – user1767476

+0

MySQL解决方案不起作用。我收到错误:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:表'my_schema.hibernate_sequence'不存在 –

0

在调用persist()方法之前,请执行以下步骤。

首先脱离当前的实例

getEntityManager().detach(getInstance()); 

现在设置了Id为null

getInstance().setId(null); 

现在坚持

String outcome = persist(); 
+0

我不能这样做,因为有两个不同的实体。如果我更新,那么添加到db的import.sql中的第一个实体将会丢失。 – user1767476

+0

我修改了我的答案。检查它是否会帮助你。 – prageeth

+0

非常感谢,但这并没有帮助。发生同样的错误信息。 – user1767476

相关问题