Hibernate: More than one row with the given identifier was found error

Hibernate

Hibernate Problem Overview


I'm using spring 4.0.5 and hibernate 4.3.5; I'm facing an error with hibernate and I can't figure where I'm wrong (because I'm sure I'm wrong). I have a table related with itself, it represents a web tree where each root node can have several children, so I created this class:

@DynamicUpdate
@Cache(region = "it.eng.angelo.spring.dao.hibernate.models.WebTree", usage = CacheConcurrencyStrategy.READ_WRITE)
@Entity
@Table(name = "MEDIA_GALL_TREE", indexes = {@Index(name = "NOME_FOLDER_IDX", columnList = "NOME_FOLDER")})
public class WebTree extends AbstractModel
{

	private static final long serialVersionUID = -4572195412018767502L;
	private long id;
	private String text;
	private boolean opened;
	private boolean disabled;
	private boolean selected;
	private Set<WebTree> children = new HashSet<WebTree>(0);
	private Set<Media> media = new HashSet<Media>(0);
	private WebTree father;
	private WcmDomain dominio;
	public WebTree()
	{
		super();
	}
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID_FOLDER", unique = true, nullable = false)
	public long getId()
	{
		return id;
	}
	public void setId(long id)
	{
		this.id = id;
	}
	@Column(name = "NOME_FOLDER", nullable = false, unique=false)
	public String getText()
	{
		return text;
	}
	public void setText(String text)
	{
		this.text = text;
	}
	@Column(name = "OPENED_FOLDER")
	public boolean isOpened()
	{
		return opened;
	}
	public void setOpened(boolean opened)
	{
		this.opened = opened;
	}
	@Column(name = "DISABLED_FOLDER")
	public boolean isDisabled()
	{
		return disabled;
	}
	public void setDisabled(boolean disabled)
	{
		this.disabled = disabled;
	}
	@Column(name = "SELECTED_FOLDER")
	public boolean isSelected()
	{
		return selected;
	}
	public void setSelected(boolean selected)
	{
		this.selected = selected;
	}
	@OneToMany(mappedBy = "father", orphanRemoval = true, targetEntity = WebTree.class)
	public Set<WebTree> getChildren()
	{
		return children;
	}
	public void setChildren(Set<WebTree> children)
	{
		this.children = children;
	}
	@ManyToOne(targetEntity = WebTree.class)
	@JoinColumn(name = "ID_PADRE", nullable = true)
	public WebTree getFather()
	{
		return father;
	}
	public void setFather(WebTree father)
	{
		this.father = father;
	}
	@OneToOne
	@JoinColumn(name="ID_DOMINIO", nullable=false)
	public WcmDomain getDominio()
	{
		return dominio;
	}
	public void setDominio(WcmDomain dominio)
	{
		this.dominio = dominio;
	}
	@OneToMany(	mappedBy = "folder", orphanRemoval = true, targetEntity = Media.class, cascade = { CascadeType.ALL })
	public Set<Media> getMedia()
	{
		return media;
	}
	public void setMedia(Set<Media> media)
	{
		this.media = media;
	}
	
}

As you can see...it's a pretty simple POJO class; now I created this unit test:

@Test
public void testLoadModifyTree()
{
	try
	{
		DetachedCriteria dc = DetachedCriteria.forClass(MediaGalleryTree.class);
		dc.setFetchMode("father", FetchMode.JOIN);
		dc.add(Property.forName("id").eq(4l));
		List<MediaGalleryTree> result = hibSvc.search(dc, IConstants.NO_PAGINATION, IConstants.NO_PAGINATION);
		for (MediaGalleryTree mediaGalleryTree : result)
		{
			logger.info(mediaGalleryTree.getId());
		}
	}
	catch (Exception e)
	{
		logger.error(e.getMessage(), e);
	}
}

Well, I checked and in the DB I have only 1 record with ID 4; well when I execute this query I got the following error:

18:48:43,123 ERROR [WcmHibernateDao] Errore nella ricerca con detached criteria DetachableCriteria(CriteriaImpl(it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree:this[][id=4])); More than one row with the given identifier was found: 2, for class: it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree
org.hibernate.HibernateException: More than one row with the given identifier was found: 2, for class: it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree
	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:100)
	at org.hibernate.loader.entity.EntityLoader.loadByUniqueKey(EntityLoader.java:161)
	at org.hibernate.persister.entity.AbstractEntityPersister.loadByUniqueKey(AbstractEntityPersister.java:2385)
	at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:767)
	at org.hibernate.type.EntityType.resolve(EntityType.java:505)
	at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:170)
	at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:144)
	at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1114)
	at org.hibernate.loader.Loader.processResultSet(Loader.java:972)
	at org.hibernate.loader.Loader.doQuery(Loader.java:920)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
	at org.hibernate.loader.Loader.doList(Loader.java:2553)
	at org.hibernate.loader.Loader.doList(Loader.java:2539)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
	at org.hibernate.loader.Loader.list(Loader.java:2364)
	at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1682)
	at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
	at it.eng.comi.spring.dao.WcmHibernateDao.searchEntity(WcmHibernateDao.java:140)
	at it.eng.comi.spring.service.impl.WcmRdbmsExtSvcImpl.search(WcmRdbmsExtSvcImpl.java:237)
	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:606)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
	at com.sun.proxy.$Proxy45.search(Unknown Source)
	at it.eng.comi.test.ComiTests.testLoadModifyTree(ComiTests.java:578)
	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:606)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
18:48:43,135 ERROR [WcmRdbmsExtSvcImpl] Errore nella ricerca con deatchedCriteria DetachableCriteria(CriteriaImpl(it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree:this[][id=4])); Errore nella ricerca con detached criteria DetachableCriteria(CriteriaImpl(it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree:this[][id=4])); More than one row with the given identifier was found: 2, for class: it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree
it.eng.comi.exception.CoMiDbException: Errore nella ricerca con detached criteria DetachableCriteria(CriteriaImpl(it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree:this[][id=4])); More than one row with the given identifier was found: 2, for class: it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree
	at it.eng.comi.spring.dao.WcmHibernateDao.searchEntity(WcmHibernateDao.java:146)
	at it.eng.comi.spring.service.impl.WcmRdbmsExtSvcImpl.search(WcmRdbmsExtSvcImpl.java:237)
	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:606)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
	at com.sun.proxy.$Proxy45.search(Unknown Source)
	at it.eng.comi.test.ComiTests.testLoadModifyTree(ComiTests.java:578)
	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:606)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.HibernateException: More than one row with the given identifier was found: 2, for class: it.eng.comi.spring.dao.hibernate.models.MediaGalleryTree
	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:100)
	at org.hibernate.loader.entity.EntityLoader.loadByUniqueKey(EntityLoader.java:161)
	at org.hibernate.persister.entity.AbstractEntityPersister.loadByUniqueKey(AbstractEntityPersister.java:2385)
	at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:767)
	at org.hibernate.type.EntityType.resolve(EntityType.java:505)
	at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:170)
	at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:144)
	at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1114)
	at org.hibernate.loader.Loader.processResultSet(Loader.java:972)
	at org.hibernate.loader.Loader.doQuery(Loader.java:920)
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
	at org.hibernate.loader.Loader.doList(Loader.java:2553)
	at org.hibernate.loader.Loader.doList(Loader.java:2539)
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2369)
	at org.hibernate.loader.Loader.list(Loader.java:2364)
	at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:126)
	at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1682)
	at org.hibernate.internal.CriteriaImpl.list(CriteriaImpl.java:380)
	at it.eng.comi.spring.dao.WcmHibernateDao.searchEntity(WcmHibernateDao.java:140)
	... 43 more

When the code is executed, hibernate print these queries:

Hibernate: 
    select
        this_.ID_FOLDER as ID_FOLDE1_7_2_,
        this_.UT_INS as UT_INS2_7_2_,
        this_.DT_INS as DT_INS3_7_2_,
        this_.DT_UPD as DT_UPD4_7_2_,
        this_.UT_UPD as UT_UPD5_7_2_,
        this_.DISABLED_FOLDER as DISABLED6_7_2_,
        this_.ID_DOMINIO as ID_DOMI10_7_2_,
        this_.ID_PADRE as ID_PADR11_7_2_,
        this_.OPENED_FOLDER as OPENED_F7_7_2_,
        this_.SELECTED_FOLDER as SELECTED8_7_2_,
        this_.NOME_FOLDER as NOME_FOL9_7_2_,
        wcmdomain2_.ID_DOMINIO as ID_DOMIN1_8_0_,
        wcmdomain2_.UT_INS as UT_INS2_8_0_,
        wcmdomain2_.DT_INS as DT_INS3_8_0_,
        wcmdomain2_.DT_UPD as DT_UPD4_8_0_,
        wcmdomain2_.UT_UPD as UT_UPD5_8_0_,
        wcmdomain2_.WCM_NOME_DOMINIO as WCM_NOME6_8_0_,
        mediagalle3_.ID_FOLDER as ID_FOLDE1_7_1_,
        mediagalle3_.UT_INS as UT_INS2_7_1_,
        mediagalle3_.DT_INS as DT_INS3_7_1_,
        mediagalle3_.DT_UPD as DT_UPD4_7_1_,
        mediagalle3_.UT_UPD as UT_UPD5_7_1_,
        mediagalle3_.DISABLED_FOLDER as DISABLED6_7_1_,
        mediagalle3_.ID_DOMINIO as ID_DOMI10_7_1_,
        mediagalle3_.ID_PADRE as ID_PADR11_7_1_,
        mediagalle3_.OPENED_FOLDER as OPENED_F7_7_1_,
        mediagalle3_.SELECTED_FOLDER as SELECTED8_7_1_,
        mediagalle3_.NOME_FOLDER as NOME_FOL9_7_1_ 
    from
        MEDIA_GALL_TREE this_ 
    inner join
        WCM_DOMAIN wcmdomain2_ 
            on this_.ID_DOMINIO=wcmdomain2_.ID_DOMINIO 
    left outer join
        MEDIA_GALL_TREE mediagalle3_ 
            on this_.ID_PADRE=mediagalle3_.ID_FOLDER 
    where
        this_.ID_FOLDER=?
Hibernate: 
    select
        mediagalle0_.ID_FOLDER as ID_FOLDE1_7_2_,
        mediagalle0_.UT_INS as UT_INS2_7_2_,
        mediagalle0_.DT_INS as DT_INS3_7_2_,
        mediagalle0_.DT_UPD as DT_UPD4_7_2_,
        mediagalle0_.UT_UPD as UT_UPD5_7_2_,
        mediagalle0_.DISABLED_FOLDER as DISABLED6_7_2_,
        mediagalle0_.ID_DOMINIO as ID_DOMI10_7_2_,
        mediagalle0_.ID_PADRE as ID_PADR11_7_2_,
        mediagalle0_.OPENED_FOLDER as OPENED_F7_7_2_,
        mediagalle0_.SELECTED_FOLDER as SELECTED8_7_2_,
        mediagalle0_.NOME_FOLDER as NOME_FOL9_7_2_,
        wcmdomain1_.ID_DOMINIO as ID_DOMIN1_8_0_,
        wcmdomain1_.UT_INS as UT_INS2_8_0_,
        wcmdomain1_.DT_INS as DT_INS3_8_0_,
        wcmdomain1_.DT_UPD as DT_UPD4_8_0_,
        wcmdomain1_.UT_UPD as UT_UPD5_8_0_,
        wcmdomain1_.WCM_NOME_DOMINIO as WCM_NOME6_8_0_,
        mediagalle2_.ID_FOLDER as ID_FOLDE1_7_1_,
        mediagalle2_.UT_INS as UT_INS2_7_1_,
        mediagalle2_.DT_INS as DT_INS3_7_1_,
        mediagalle2_.DT_UPD as DT_UPD4_7_1_,
        mediagalle2_.UT_UPD as UT_UPD5_7_1_,
        mediagalle2_.DISABLED_FOLDER as DISABLED6_7_1_,
        mediagalle2_.ID_DOMINIO as ID_DOMI10_7_1_,
        mediagalle2_.ID_PADRE as ID_PADR11_7_1_,
        mediagalle2_.OPENED_FOLDER as OPENED_F7_7_1_,
        mediagalle2_.SELECTED_FOLDER as SELECTED8_7_1_,
        mediagalle2_.NOME_FOLDER as NOME_FOL9_7_1_ 
    from
        MEDIA_GALL_TREE mediagalle0_ 
    inner join
        WCM_DOMAIN wcmdomain1_ 
            on mediagalle0_.ID_DOMINIO=wcmdomain1_.ID_DOMINIO 
    left outer join
        MEDIA_GALL_TREE mediagalle2_ 
            on mediagalle0_.ID_PADRE=mediagalle2_.ID_FOLDER 
    where
        mediagalle0_.ID_DOMINIO=?

These are my table records:

id_folder; ut_ins; dt_ins; dt_upd; ut_upd; disabled_folder; opened_folder; selected_folder; nome_folder; id_dominio; id_padre
"1";"system";"2014-06-12 18:23:16.649";"2014-06-12 18:23:16.649";"system";FALSE;FALSE;FALSE;"Root 1";1;
"2";"system";"2014-06-12 18:23:16.662";"2014-06-12 18:23:16.662";"system";FALSE;FALSE;FALSE;"Root 2";2;
"4";"wpsAdmin";"2014-06-13 16:18:01.428";"2014-06-13 18:12:14.228";"wpsAdmin";FALSE;FALSE;FALSE;"Testina";2;2
"7";"wpsAdmin";"2014-06-13 17:33:05.575";"2014-06-13 17:33:10.275";"wpsAdmin";FALSE;FALSE;FALSE;"Angelo";2;2

May anybody tell me where I'm wrong? It seems to me all correct....any tips is welcome

Thank you Angelo

Just a note: all works pretty good if I chenge my POJO class method getChildern in this way:

@OneToMany(	mappedBy = "father", targetEntity = WebTree.class, fetch=FetchType.EAGER)
public Set<WebTree> getChildren()
{
	return children;
}

But I'm wondering why this behaviour?

Thank you Angelo

Hibernate Solutions


Solution 1 - Hibernate

I got bit by the org.hibernate.HibernateException: More than one row with the given identifier was found: problem and found no help on StackOverflow. It took awhile to sort out the issue so I'm documenting the solution here. I was using JPA/Hibernate and Spring Data.

First off, this was not caused by duplicate rows in the database, as it's obviously not possible to have duplicate primary keys. Instead this was caused by Hibernate looking up an object, and eagerly filling in a One-to-one relationship with a LEFT OUTER JOIN. Hibernate assumed a single row would come back, but two came back because there were two objects associated with the one-to-one relationship.

Here's a simplified version of my objects:

@Entity
@Table(name = "plate")
public class Plate {
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name="test_seq", sequenceName="test_seq")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "test_seq")
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "object_version")
    private long objectVersion;

    @Column(name = "name")
    private String name;

    @OneToOne(mappedBy = "plate")
    private Sheet sheet;
    
    public Sheet getSheet() {
        return sheet;
    }

    public void setSheet(Sheet sheet) {
        if (this.sheet != null) {
            this.sheet.setPlate(null);
        }

        this.sheet = sheet;
        sheet.setPlate(this);
    }
}


@Entity
@Table(name = "sheet")
public class Sheet {
    private static final long serialVersionUID = 1L;

    @Id
    @SequenceGenerator(name="test_seq", sequenceName="test_seq")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "test_seq")
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "object_version")
    private long objectVersion;

    @Column(name = "sheet_name")
    private String sheetName;

    @OneToOne
    @JoinColumn(name = "plate_id")
    private Plate plate;
    
    public Plate getPlate() {
        return plate;
    }

    // Do not use. Use Plate.setSheet() instead
    void setPlate(Plate plate) {
        this.plate = plate;
    }
}

The problem is with the @OneToOne relationship between Plate and Sheet. I initially did not want to delete orphan Sheets. In my code I looked up a Plate by id and added a new Sheet. This removed the Plate-to-Sheet relationship from the original Sheet. When I commit the transaction I assumed JPA would save all modified objects (Plate, the original Sheet, and the new Sheet).

This was not true! JPA apparently finds modified objects by walking down the hierarchy from the object that was originally loaded (Plate), and it misses the fact that the original Sheet, which is now orphaned, was modified. This meant the original Sheet's sheet.plate_id column was not cleared in the database. In other words, I broke their relationship in the data model, but it failed to save to the database. So the next time I try to load the plate Hibernate runs a query like this:

select
    plate1_.id as id1_19_12_, 
    plate1_.object_version as object_v2_19_12_, 
    plate1_.name as name3_19_12_, 
    sheet2_.id as id1_39_12_, 
    sheet2_.object_version as object_v2_39_12_, 
    sheet2_.sheet_name as sheet_nam2_39_12_, 
    sheet2_.plate_id as plate_id4_39_12_, 
from 
    plate plate1_
    left outer join sheet sheet2_ on plate1_.id = sheet2_.plate_id
where 
    plate1_.id=?

Which brings back 2 rows in the result set and produces this error:

org.hibernate.HibernateException: More than one row with the given identifier was found: 10045, for class: com.example.Plate

This is deceptive: there is only one Plate row with that id in the database, but there are two Sheets linked to it.

The solution: Seems I have two choices: either cascade all and delete orphan on the one-to-one relationship, or explicitly call my repository class to look up and save the original Sheet every time I remove its relationship with Plate. I opted for the first choice and added this to the plate class:

@OneToOne(mappedBy = "plate", cascade = CascadeType.ALL, orphanRemoval = true)
private Sheet sheet;

This fixed the issue.

Solution 2 - Hibernate

I'm sorry; it was my mistake......in my entity class I wrongly mapped a relation as oneToOne; it was, instead, oneToMany :) Now all works pretty good.....; this is my new entity class:

@DynamicUpdate
@Cache(region = "it.eng.angelo.spring.dao.hibernate.models.MediaGalleryTree", usage = CacheConcurrencyStrategy.READ_WRITE)
@Entity
@Table(name = "MEDIA_GALL_TREE", indexes = {@Index(name = "NOME_FOLDER_IDX", columnList = "NOME_FOLDER")})
public class MediaGalleryTree extends AbstractModel
{

	private static final long serialVersionUID = -4572195412018767502L;
	private long id;
	private String text;
	private boolean opened;
	private boolean disabled;
	private boolean selected;
	private Set<MediaGalleryTree> children = new HashSet<MediaGalleryTree>(0);
	private Set<FedoraCommonsEntity> media = new HashSet<FedoraCommonsEntity>(0);
	private MediaGalleryTree father;
	private WcmDomain dominio;
	public MediaGalleryTree()
	{
		super();
	}
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID_FOLDER", unique = true, nullable = false)
	public long getId()
	{
		return id;
	}
	public void setId(long id)
	{
		this.id = id;
	}
	@Column(name = "NOME_FOLDER", nullable = false, unique=false)
	public String getText()
	{
		return text;
	}
	public void setText(String text)
	{
		this.text = text;
	}
	@Column(name = "OPENED_FOLDER")
	public boolean isOpened()
	{
		return opened;
	}
	public void setOpened(boolean opened)
	{
		this.opened = opened;
	}
	@Column(name = "DISABLED_FOLDER")
	public boolean isDisabled()
	{
		return disabled;
	}
	public void setDisabled(boolean disabled)
	{
		this.disabled = disabled;
	}
	@Column(name = "SELECTED_FOLDER")
	public boolean isSelected()
	{
		return selected;
	}
	public void setSelected(boolean selected)
	{
		this.selected = selected;
	}
	@OneToMany(	mappedBy = "father", orphanRemoval = true, 
				targetEntity = MediaGalleryTree.class)
	public Set<MediaGalleryTree> getChildren()
	{
		return children;
	}
	public void setChildren(Set<MediaGalleryTree> children)
	{
		this.children = children;
	}
	@ManyToOne(targetEntity = MediaGalleryTree.class)
	@JoinColumn(name = "ID_PADRE", nullable = true)
	public MediaGalleryTree getFather()
	{
		return father;
	}
	public void setFather(MediaGalleryTree father)
	{
		this.father = father;
	}
	@ManyToOne(targetEntity = WcmDomain.class, cascade={CascadeType.ALL})
	@JoinColumn(name="ID_DOMINIO", nullable=false)
	public WcmDomain getDominio()
	{
		return dominio;
	}
	public void setDominio(WcmDomain dominio)
	{
		this.dominio = dominio;
	}
	@OneToMany(	mappedBy = "folder", orphanRemoval = true, 
			targetEntity = Media.class, cascade = { CascadeType.ALL })
	public Set<FedoraCommonsEntity> getMedia()
	{
		return media;
	}
	public void setMedia(Set<FedoraCommonsEntity> media)
	{
		this.media = media;
	}
	
}

Angelo

Solution 3 - Hibernate

If you have @OneToOne mapping in your class then update the fetch type to LAZY. Because by default fetch type for OneToOne is EAGER so when we fetch object of main class (WebTree) class, it will fetch the object for OneToOne mapped class so when hibernate map the object it will throw the exception. In Short if you have OneToOne Mapping then replace it with @OneToOne(fetch = FetchType.LAZY).

Solution 4 - Hibernate

Neither of above solutions worked for my case. I only could make it work by changing from bidirectional one-to-one relationship to unidirectional one-to-one relationship.

Solution 5 - Hibernate

I had the same problem and I also change the mapping from OneToOne mapping to OneToMany mapping. Previously, I have defined the mapping as OneToOne mistakenly. Now it's working properly.

Old

@OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
	@JoinColumn(name="appointmentId", nullable=false, insertable=false, updatable=false)
	private Appointment appointment;

Current

@ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
	@JoinColumn(name="appointmentId", nullable=false, insertable=false, updatable=false)
	private Appointment appointment;

Solution 6 - Hibernate

Find in the hibernate-mapping the relationship one-to-one, after that, find in the database in the associated table, is possible that the relationship table get more than one rows

Solution 7 - Hibernate

Try to check the Entity relation @OneToOne, in your case check the WcmDomain entity, it will contain two records referring to WebTree. so once you load the WebTree by findById it will fail, as it is doing internal join and the final result will be two records.

So delete that extra record from the WcmDomain, it will work

Solution 8 - Hibernate

I had the same issue while updating the data. I solved the problem by passing the parent object with its primary key. All child object's primary key was set to null. This worked for me. Neither of above solution worked in my case.

Solution 9 - Hibernate

I had the same issue, when I am executing a native query having join of 2 tables but the Entity does not contain the fields from another table.

After lot of struggle below solution worked for me:

I simply declared the fields that are required and not present in the entity (also these fields are the same which are not present in the table that current entity represents) with its getter and setters.

Solution 10 - Hibernate

I have faced this issue in @OneToOne mapping between 2 entities / classes. There are 2 solutions to this issue:

  1. If you do not want to save both the entities at the same time / same post request, then make the OneToOne mapping association UNIDIRECTIONAL and avoid Bidirectional.

  2. If you want to save both the entities at the same time using Cascade, then Make the OneToOne mapping BIDIRECTIONAL and use @TRANSIENT in the Entity / Class where you have used @MappedBy().

Let me know if it works..

Solution 11 - Hibernate

I had the same problem. Making it one directional worked for me.

Solution 12 - Hibernate

Add @JsonIgnore and change cascade to fetch:

@Getter
@Setter
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "capacitacion_id", referencedColumnName = "id")
@JsonIgnore
private Capacitacion capacitacion;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAngelo ImmediataView Question on Stackoverflow
Solution 1 - HibernateJMBView Answer on Stackoverflow
Solution 2 - HibernateAngelo ImmediataView Answer on Stackoverflow
Solution 3 - HibernateSHYAM SHARMAView Answer on Stackoverflow
Solution 4 - HibernateRyan Jeongsu HanView Answer on Stackoverflow
Solution 5 - HibernateNishantha BulumullaView Answer on Stackoverflow
Solution 6 - HibernateAdrianView Answer on Stackoverflow
Solution 7 - HibernateHany SakrView Answer on Stackoverflow
Solution 8 - HibernateJivan BhandariView Answer on Stackoverflow
Solution 9 - HibernateBhushan KatharView Answer on Stackoverflow
Solution 10 - HibernateGaurav SwainView Answer on Stackoverflow
Solution 11 - HibernatePijushView Answer on Stackoverflow
Solution 12 - HibernateEnrique AvilésView Answer on Stackoverflow