当试图保持实体时,具有相同标识符值的不同对象已经与会话相关联 [英] a different object with the same identifier value was already associated with the session when trying to persist entity

查看:686
本文介绍了当试图保持实体时,具有相同标识符值的不同对象已经与会话相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个轻微的问题,我不知道如何解决。请问你能帮帮我吗?
当我试图坚持实体时,我得到下一个异常:

  12:47:39,398错误[org.black .dmitriy.entityHome.ScheduleHome](http  -  127.0.0.1-8080-1)javax.persistence.EntityExistsException:具有相同标识符值的不同对象已与会话相关联:[org.black.dmitriy.entity.Schedule #1] 
在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)[休眠-的EntityManager-4.0.1.Final.jar:4.0.1.Final]在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.invo ke0(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:]
。在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)[rt.jar中:1.7.0_04]
。在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl。 java:57)[rt.jar:1.7.0_04]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[rt.ja r: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]
在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]
在org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:65)[jboss-seam.jar:2.3.0。最后]
在org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)[jboss-seam.jar:2.3.0.Final]
at org.jboss.seam.transaction .TransactionInterceptor $ 1.work(Transa ctionInterceptor.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]
在org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)[jboss-seam.jar:2.3.0.Final]
位于org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)[jboss-seam.jar:2.3.0.Final]
位于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]
在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]
在org.jboss.el.Metho dExpressionImpl.invoke(MethodExpressionImpl.java:276)的JBoss-EL-1.0_02.CR6.jar:1.0_02.CR6]在com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java
: 105)[JSF-IMPL-2.1.7-jbossorg-2.jar:]在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]
在javax.faces.component。 UIViewRoot.processApplication(UIViewRoot.java:1259)的jboss-JSF的api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]在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]
在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.IdentityFilte r.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]
在org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)[jboss-seam.jar:2.3.0.Final]
在org.jboss.seam.servlet.SeamFilter $ FilterChainImpl.doFilter(SeamFilter.java:69)[jboss-seam.jar:2.3.0.Final]
在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 $ FilterCh ainImpl.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:]
。在org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:397)[jbossweb-7.0.13.Final.jar:]
。在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:]
在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)[jbossweb-7.0.13.Final.jar:]
位于org.apache.catalina.connector.CoyoteAdapter的org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)[jbossweb-7.0.13.Final.jar:]
。服务(CoyoteAdapter.java:368)[jbossweb-7.0.13.Final.jar:]
在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:] $ b $ at java.lang.Thread.run(Thread.java:722) [rt.jar:1.7.0_04]

我使用seam 2.3,hibernate。我有一个insert语句在我的import.sql文件中:

pre $ INSERT INTO调度(id,name,dayCount, secondTermSize,subgroupSize)VALUES(1,'2012/2013',5,8,9,9,18)



然后我使用EntityHome创建新的Schedule实体抛出网页

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

公共ScheduleHome(){
}

@Override
保护布尔isUnique(){
Schedule schedule = getInstance();
Schedule foundSchedule = ScheduleDAO.instance()。getByName(schedule.getName()); ((foundSchedule!= null)&&(!foundSchedule.equals(schedule))){
showExistsErrorMessage(getInstance()。getName());


返回false;
}

返回true;
}

@Override
保护计划createInstance(){
return new Schedule();
}

@Override
public String getEditOutcome(){
returnscheduleEdit;


@Override
保护无效prepareEntityForSaving(){

}
}

和超类

  public abstract class ConversationHome< T>扩展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 prepareEntityForSaving();

protected abstract boolean isUnique();

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


protected void create(boolean createNestedConversation){
Conversation conversation = Conversation.instance();
if(!createNestedConversation&&& amp;& conversation.isLongRunning()){
getLog()。debug(对话已经开始,嵌套不会创建(isLongRunning =#0,isNested =#1) ,conversation.isLongRunning(),conversation.isNested());
} else {
conversation.begin(false,conversation.isLongRunning());
conversation.changeFlushMode(FlushModeType.MANUAL);
getLog().delete(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);
尝试{
getInstance();
getLog()。debug(instance initialized#0,getInstance());
} catch(EntityNotFoundException e){
getLog()。error(e);
返回false;
}
}
返回true;
}

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


$ b $ public String cancel(){
if(isManaged()){
getEntityManager()。refresh(getInstance());
}
return returnToParent();

$ b $ end
protected String returnToParent(){
if(isParentViewExists()){
Conversation conversation = Conversation.instance();
getLog()。debug(结束会话(id =#0,isLongRunning =#1,isNested =#2),
conversation.getId(),conversation.isLongRunning(),conversation.isNested ());
conversation.end(true);
return getParentView();
} else {
clearInstance();
返回null;



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

字符串结果= persist();
if(!failed.equals(outcome)){
return returnToParent();
}
} catch(Exception e){
getLog()。error(getInstance(),e);
showSaveErrorMessage(e);
}
}
返回失败;


$ / code>

当我试图坚持它时,我得到这个异常。和消息在网页上



用消息保存错误:具有相同标识符值的不同对象已与会话相关联:[org.black.dmitriy.entity.Schedule #1]



它将hibernate的id属性设为1,但我已经拥有 id = 1 ,因为我手动创建了它,它引发了import.sql。

这是我的Schedule实体:

  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)
公共课程计划{

@Id
@GeneratedValue
@Column(name =id,nullable = false)
私人长ID;

@NotNull
@Column(name =name,nullable = false,length = 40)
私有字符串名称;

@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 Sc​​hedule(){

}

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

公共列表< 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());
返回结果;

$ b @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;
}
返回true;
}

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






$ b

正如你所看到的那样,id上有@GeneratedValue注解属性,所以我认为hibernate应该自己生成id,并且hibernate应该知道id = 1的数据库中存在实体,并且在新实体= 2中设置了id。但是,Hibernate将id设置为新实体。
可能你请求我吗?

解决方案

问题在于hibernate如何产生你的 id ,它从1开始。当它将1保存到数据库之前将其分配给对象时,它会在数据库中看到一个具有相同ID的行,并导致异常。这个问题的简单和自然的解决方案是简单地限制hibernate,以便它不能将 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; //通过hibernate分配id,将从2开始。

并且在您的域类中,您可以使用id注释如下:

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

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

Oracle解决方案:



如果限制hibernate使用序列,并且根据需要设置序列的初始点,那么对于oracle可以做同样的事情。您可以创建一个从 2 开始的序列,并按照以下方式增加 1

 创建序列id序列
以2开始
按1加
maxvalue 9999999999999;

你可以指定你的序列来生成你的领域类的对象的id,如下所示: / p>

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

并且您的问题已被解决。


I have a slight problem that I don't know how to solve. Could you help me please? When I am trying to persist entity I get next exception:

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]

I use seam 2.3, hibernate. I have one insert statement in my import.sql file:

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

which inserts one enity into table Schedules.

Then I create new Schedule entity throw web page using 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() {

    }
}

and the superclass

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";
    }
}

and when i try to persist it i get this exception. and message on web page

Save error with message: a different object with the same identifier value was already associated with the session: [org.black.dmitriy.entity.Schedule#1]

It seams that hibernate set id property to 1, but I already have entity with id = 1, because I manually created it throw import.sql.

Here is my Schedule entity :

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

As you can see there is @GeneratedValue annotation on id property, so I think that hibernate should generate id himself and hibernate should know that there is entity in database with id = 1, and set id in new entity = 2. But Hibernate sets id in new entity to 1. Could you halp me please?

解决方案

The problem was how hibernate generates your id's, it starts from 1. When it assigns 1 to an object before saving it into database, it sees a row with same id already exists in the database and causes the exception. The simple and natural solution of this problem is simply to restrict hibernate, so that it can not assign 1 as an id to any object of the concerning class (in your case).

Solution for mySql:

If you are using mySql, you can create table manually and set the auto increment like:

  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.

And in your domain class you can have id annotated like bellow:

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

GenerationType.AUTO by default uses auto increment in mySql. and after setting AUTO_INCREMENT=2 hibernate will start assigning id's from 2 (hence 1 is skipped).

Solution for Oracle:

The same thing for oracle can be done if you restrict hibernate use a "sequence" and you set the initial point of the sequence as your wish. You can create a sequence to be start from 2 and increment by 1 like bellow:

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

And you can specify your sequence to be used to generate id's of your domain class's object like bellow:

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

And your problem is sovled.

这篇关于当试图保持实体时,具有相同标识符值的不同对象已经与会话相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆