Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 335277 - An aggregate Set is changed without making any changes -> forced an UpdateObjectQuery
Summary: An aggregate Set is changed without making any changes -> forced an UpdateObj...
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-25 02:07 EST by Thorsten Ruth CLA
Modified: 2022-06-09 10:08 EDT (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thorsten Ruth CLA 2011-01-25 02:07:20 EST
Build Identifier: 20100617-1415

Assume an entity class A which contained an aggregate set of class B.

Classes:

class A {
    private Set<B> bees;

    public Set<B> getBees() {
		List<B> bList = new ArrayList<B>(bees);     //
		Collections.reverse(bList);                 // <- useless, but pictures the error
		return new HashSet<B>(bList);
    }

    public void setNicknames(final Set<B> bees) {
        this.bees = bees;
    }
}

class B {
    ...
}

orm.xml:

<entity-mappings>
	<entity class="A" access="PROPERTY">
		<table name="A"></table>
		<attributes>
			<element-collection name="bees" target-class="B">
				<collection-table name="B">
					<join-column name="a" />
				</collection-table>
			</element-collection>
		</attributes>
	</entity>
	<embeddable class="B">
		<attributes>
            ...
		</attributes>
	</embeddable>
</entity-mappings>

Test-Run:

entityManager.getTransaction().begin();
Query query = entityManager.createQuery("SELECT a FROM A a");
A a = query.getSingleResult();
entityManager.getTransaction().commit();


Enable full query logging (ALL) and you will see UpdateObjectQuerys for every element in Set<B>. This shouldn't happen, because nothing has changed.
Since sets have no explicid order, the set bees and its reversed version (see the getter of bee) have to be equal in mathematical sense.

After we debugging this issue, we found where the invalid set comparison take place. This comparison is valid for ordered collections but not for unordered collections.

org.eclipse.persistence.mappings.AggregateCollectionMapping.compareForChange(Object clone, Object backUp, ObjectChangeSet owner, AbstractSession session):
...
            while (cp.hasNext(cloneIterator)) {
                Object cloneObject = cp.next(cloneIterator, session);

                // For CR#2285 assume that if null is added the collection has changed.
                if (cloneObject == null) {
                    change = true;
                    break;
                }
                Object backUpObject = null;
                if (cp.hasNext(backUpIterator)) {
                    backUpObject = cp.next(backUpIterator, session);
                } else {
                    change = true;
                    break;
                }
                if (cloneObject.getClass().equals(backUpObject.getClass())) {
...



Reproducible: Always
Comment 1 Tom Ware CLA 2011-02-03 09:52:50 EST
Setting target and priority.  See the following page for the meanings of these fields:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines
Comment 2 Eclipse Webmaster CLA 2022-06-09 10:08:10 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink