HHH-9078 correct OrderColumn indexes for inverse, extra lazy collections

Conflicts:
	hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
This commit is contained in:
Brett Meyer 2014-03-24 13:26:48 -04:00
parent ad69571543
commit 3127bb8b18
4 changed files with 32 additions and 18 deletions

View File

@ -1635,12 +1635,13 @@ public abstract class AbstractCollectionPersister
public void processQueuedOps(PersistentCollection collection, Serializable key, SessionImplementor session) public void processQueuedOps(PersistentCollection collection, Serializable key, SessionImplementor session)
throws HibernateException { throws HibernateException {
if ( collection.hasQueuedOperations() ) { if ( collection.hasQueuedOperations() ) {
doProcessQueuedOps( collection, key, session ); int nextIndex = getSize( key, session );
doProcessQueuedOps( collection, key, nextIndex, session );
} }
} }
protected abstract void doProcessQueuedOps(PersistentCollection collection, Serializable key, SessionImplementor session) protected abstract void doProcessQueuedOps(PersistentCollection collection, Serializable key,
throws HibernateException; int nextIndex, SessionImplementor session) throws HibernateException;
public CollectionMetadata getCollectionMetadata() { public CollectionMetadata getCollectionMetadata() {
return this; return this;

View File

@ -154,7 +154,8 @@ public class BasicCollectionPersister extends AbstractCollectionPersister {
} }
@Override @Override
protected void doProcessQueuedOps(PersistentCollection collection, Serializable id, SessionImplementor session) protected void doProcessQueuedOps(PersistentCollection collection, Serializable id,
int nextIndex, SessionImplementor session)
throws HibernateException { throws HibernateException {
// nothing to do // nothing to do
} }

View File

@ -181,34 +181,33 @@ public class OneToManyPersister extends AbstractCollectionPersister {
public void recreate(PersistentCollection collection, Serializable id, SessionImplementor session) public void recreate(PersistentCollection collection, Serializable id, SessionImplementor session)
throws HibernateException { throws HibernateException {
super.recreate( collection, id, session ); super.recreate( collection, id, session );
writeIndex( collection, collection.entries( this ), id, session ); writeIndex( collection, collection.entries( this ), id, 0, session );
} }
@Override @Override
public void insertRows(PersistentCollection collection, Serializable id, SessionImplementor session) public void insertRows(PersistentCollection collection, Serializable id, SessionImplementor session)
throws HibernateException { throws HibernateException {
super.insertRows( collection, id, session ); super.insertRows( collection, id, session );
writeIndex( collection, collection.entries( this ), id, session ); writeIndex( collection, collection.entries( this ), id, 0, session );
} }
@Override @Override
protected void doProcessQueuedOps(PersistentCollection collection, Serializable id, SessionImplementor session) protected void doProcessQueuedOps(PersistentCollection collection, Serializable id,
throws HibernateException { int nextIndex, SessionImplementor session) throws HibernateException {
writeIndex( collection, collection.queuedAdditionIterator(), id, session ); writeIndex( collection, collection.queuedAdditionIterator(), id, nextIndex, session );
} }
private void writeIndex(PersistentCollection collection, Iterator entries, Serializable id, SessionImplementor session) { private void writeIndex(PersistentCollection collection, Iterator entries, Serializable id,
int nextIndex, SessionImplementor session) {
// If one-to-many and inverse, still need to create the index. See HHH-5732. // If one-to-many and inverse, still need to create the index. See HHH-5732.
if ( isInverse && hasIndex && !indexContainsFormula ) { if ( isInverse && hasIndex && !indexContainsFormula ) {
try { try {
if ( entries.hasNext() ) { if ( entries.hasNext() ) {
Expectation expectation = Expectations.appropriateExpectation( getUpdateCheckStyle() ); Expectation expectation = Expectations.appropriateExpectation( getUpdateCheckStyle() );
int i = 0;
int count = 0;
while ( entries.hasNext() ) { while ( entries.hasNext() ) {
final Object entry = entries.next(); final Object entry = entries.next();
if ( entry != null && collection.entryExists( entry, i ) ) { if ( entry != null && collection.entryExists( entry, nextIndex ) ) {
int offset = 1; int offset = 1;
PreparedStatement st = null; PreparedStatement st = null;
boolean callable = isUpdateCallable(); boolean callable = isUpdateCallable();
@ -237,9 +236,9 @@ public class OneToManyPersister extends AbstractCollectionPersister {
try { try {
offset += expectation.prepare( st ); offset += expectation.prepare( st );
if ( hasIdentifier ) { if ( hasIdentifier ) {
offset = writeIdentifier( st, collection.getIdentifier( entry, i ), offset, session ); offset = writeIdentifier( st, collection.getIdentifier( entry, nextIndex ), offset, session );
} }
offset = writeIndex( st, collection.getIndex( entry, i, this ), offset, session ); offset = writeIndex( st, collection.getIndex( entry, nextIndex, this ), offset, session );
offset = writeElement( st, collection.getElement( entry ), offset, session ); offset = writeElement( st, collection.getElement( entry ), offset, session );
if ( useBatch ) { if ( useBatch ) {
@ -251,7 +250,6 @@ public class OneToManyPersister extends AbstractCollectionPersister {
else { else {
expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 ); expectation.verifyOutcome( session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate( st ), st, -1 );
} }
count++;
} }
catch ( SQLException sqle ) { catch ( SQLException sqle ) {
if ( useBatch ) { if ( useBatch ) {
@ -266,7 +264,7 @@ public class OneToManyPersister extends AbstractCollectionPersister {
} }
} }
i++; nextIndex++;
} }
} }
} }

View File

@ -404,8 +404,22 @@ public class OrderByTest extends BaseCoreFunctionalTestCase {
forum = (Forum) s.get( Forum.class, forum.getId() ); forum = (Forum) s.get( Forum.class, forum.getId() );
assertEquals( 1, forum.getPosts().size() ); final Post post2 = new Post();
post2.setName( "post2" );
post2.setForum( forum );
forum.getPosts().add( post2 );
forum = (Forum) s.merge( forum );
s.flush();
s.clear();
sessionFactory().getCache().evictEntityRegions();
forum = (Forum) s.get( Forum.class, forum.getId() );
assertEquals( 2, forum.getPosts().size() );
assertEquals( "post1", forum.getPosts().get( 0 ).getName() ); assertEquals( "post1", forum.getPosts().get( 0 ).getName() );
assertEquals( "post2", forum.getPosts().get( 1 ).getName() );
assertEquals( 1, forum.getUsers().size() ); assertEquals( 1, forum.getUsers().size() );
assertEquals( "john", forum.getUsers().get( 0 ).getName() ); assertEquals( "john", forum.getUsers().get( 0 ).getName() );
} }