[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.tools.emf] Re: [Teneo] Possible inconsistency using IdBags

Hi Bjoern,
I tried to replicate this in a test but I was not able to (with me it works fine). Also in my case I change the list which is last in the database. I have attached the test I used, it uses the Teneo test framework but I am sure you can read through it. In addition I attached the ecore model I used to test. Can you check if you see any differences?


Otherwise if you have a test case for me then I can try it out.

gr. Martin

Bjoern Sundin wrote:
Hello Martin,

I have encountered a problem concerning lists in my application. After extensive debugging I have found out that this problem is connected with the use of IdBags.

I use Eclipse 3.4, Teneo 1.0.1 and Hibernate 3.3.1 (also tested with 3.2.6)

The problem is the following:
When adding objects to a list, one part of the logic first makes list.clear() and then adds all the newly submitted objects. The newly submitted objects could possibly partly contain the once removed in list.clear().
This is no problem unless the list being modified is the one having the last rows in the database table! In this case only the new objects get added to the list. The ones removed and then readded do not get persisted to the database again. They are visible to the GUI (model), however, but only until the application restarts.


The situation as an example:
Object Library has a unique ordered non-containment list referencing object Book (Books are contained in object Publisher).


In the database there is a table Library _ Books with three columns:
Library id | Book id | ID

To start the following ids are in the table:
 1|11|1
 1|12|2
 1|13|3
 2|11|4
 2|13|5

- I edit the list for the Library with id 2 in the GUI. I want to add a Book reference with id 12.

- The logic makes list.clear() and thus removes all the Book references (11 and 13) for the Library with id 2.

- Then it adds the Book references 11, 12 and 13

- The transaction gets committed.

- The Model (EObjects) shows the following two lists:
 1{11, 12, 13}
 2{11, 12, 13}

- In the database I have the following:
 1|11|1
 1|12|2
 1|13|3
 2|12|4

- The expected result in the database would be
 1|11|1
 1|12|2
 1|13|3
 2|11|4
 2|12|5
 2|13|6

I'm able to resolve this behaviour by setting the PersistenceOptions.MAP_ALL_LISTS_AS_IDBAG to false and recreate the database. But I think it might be important to know about the impact of this problem when using IdBags as it (for me) unexpectedly removed entries from the database.

Greetings
Bjoern





--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Cell: +31 (0)6 288 48 943
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@xxxxxxxxxxxxxx - mtaal@xxxxxxxxx
Web: www.springsite.com - www.elver.org
/**
 * <copyright>
 *
 * Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Martin Taal
 * </copyright>
 *
 * $Id: LibraryListAsBagAction.java,v 1.3 2008/02/28 07:08:15 mtaal Exp $
 */

package org.eclipse.emf.teneo.test.emf.sample;

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

import org.eclipse.emf.teneo.PersistenceOptions;
import org.eclipse.emf.teneo.samples.issues.bz237790.Bz237790Factory;
import org.eclipse.emf.teneo.samples.issues.bz237790.Bz237790Package;
import org.eclipse.emf.teneo.samples.issues.bz237790.Many;
import org.eclipse.emf.teneo.samples.issues.bz237790.One;
import org.eclipse.emf.teneo.test.AbstractTestAction;
import org.eclipse.emf.teneo.test.stores.TestStore;

/**
 * @author <a href="mailto:mtaal@xxxxxxxxx";>Martin Taal</a>
 * @version $Revision: 1.3 $
 */
public class ListAsIdBagAction extends AbstractTestAction {

	private final Bz237790Factory factory = Bz237790Factory.eINSTANCE;

	public ListAsIdBagAction() {
		super(Bz237790Package.eINSTANCE);
	}

	@Override
	public Properties getExtraConfigurationProperties() {
		final Properties props = new Properties();
		props.setProperty(PersistenceOptions.MAP_ALL_LISTS_AS_IDBAG, "true");
		return props;
	}

	@Override
	public void doAction(TestStore store) {
		store.disableDrop();
		{
			store.beginTransaction();
			addDataSet(store, 1);
			addDataSet(store, 2);
			store.commitTransaction();
		}

		// read the writers and add the second book to the second writer
		{
			store.beginTransaction();
			final List<One> os = store.getObjects(One.class);
			One o1 = null;
			One o2 = null;
			for (One o : os) {
				if (o.getManies().size() == 2) {
					o1 = o;
				} else {
					o2 = o;
				}
			}
			final List<Many> reserve = new ArrayList<Many>(o1.getManies());
			o1.getManies().clear();
			reserve.add(1, o2.getManies().get(1));
			o1.getManies().addAll(reserve);
			store.commitTransaction();
		}

		{
			store.beginTransaction();
			final List<One> os = store.getObjects(One.class);
			for (One o : os) {
				assertEquals(3, o.getManies().size());
			}
			store.commitTransaction();
		}
	}

	private void addDataSet(TestStore store, int index) {
		{
			final One one = factory.createOne();
			store.store(one);
			int num = 3;
			if (index == 2) {
				num = 2;
			}
			for (int i = 0; i < num; i++) {
				final Many many = factory.createMany();
				many.setName("" + index);
				one.getManies().add(many);
				store.store(many);
			}
		}

	}
}
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0"
    xmlns:xmi="http://www.omg.org/XMI"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"; name="bz237790"
    nsURI="http://www.eclipse.org/emf/teneo/samples/issues/bz225296"; nsPrefix="bz237790">
  <eClassifiers xsi:type="ecore:EClass" name="One">
    <eStructuralFeatures xsi:type="ecore:EReference" name="manies" upperBound="-1"
        eType="#//Many" resolveProxies="false"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Many">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString";>
      <eAnnotations source="teneo.jpa">
        <details key="value" value="@Column(name=&quot;myname&quot;)"/>
      </eAnnotations>
    </eStructuralFeatures>
  </eClassifiers>
</ecore:EPackage>