From 5e873979029f24e9c4498d3869c96dbf45c5b3e7 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 16 Nov 2015 22:03:27 -0600 Subject: [PATCH] HHH-9195 - Adding an entity at a given index in a list annotated with OrderColumn adds the entity at the end --- .../collection/internal/PersistentList.java | 2 +- ...ListIndexReferenceFromListElementTest.java | 139 ++++++++++++++++++ .../src/test/resources/log4j.properties | 5 +- 3 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/test/collection/list/ListIndexReferenceFromListElementTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/collection/internal/PersistentList.java b/hibernate-core/src/main/java/org/hibernate/collection/internal/PersistentList.java index 0ad78cf0c3..66cabbc604 100644 --- a/hibernate-core/src/main/java/org/hibernate/collection/internal/PersistentList.java +++ b/hibernate-core/src/main/java/org/hibernate/collection/internal/PersistentList.java @@ -315,7 +315,7 @@ public class PersistentList extends AbstractPersistentCollection implements List if ( index < 0 ) { throw new ArrayIndexOutOfBoundsException( "negative index" ); } - if ( !isInitialized() && isConnectedToSession() ) { + if ( !isInitialized() || isConnectedToSession() ) { // NOTE : we don't care about the inverse part here because // even if the collection is inverse, this side is driving the // writing of the indexes. And because this is a positioned-add diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/list/ListIndexReferenceFromListElementTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/list/ListIndexReferenceFromListElementTest.java new file mode 100644 index 0000000000..1cd452d8b6 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/collection/list/ListIndexReferenceFromListElementTest.java @@ -0,0 +1,139 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.test.collection.list; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OrderColumn; +import javax.persistence.Table; + +import org.hibernate.Session; + +import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +/** + * Test initially developed for HHH-9195 + * @author Steve Ebersole + */ +public class ListIndexReferenceFromListElementTest extends BaseNonConfigCoreFunctionalTestCase { + @Entity( name = "LocalOrder" ) + @Table( name = "LocalOrder" ) + public static class LocalOrder { + @Id + @GeneratedValue + public Integer id; + @OneToMany( mappedBy = "order", cascade = CascadeType.ALL, fetch = FetchType.LAZY ) + @OrderColumn( name = "position" ) + public List lineItems = new ArrayList(); + + public LocalOrder() { + } + + public LocalLineItem makeLineItem(String name) { + LocalLineItem lineItem = new LocalLineItem( name, this ); + lineItems.add( lineItem ); + return lineItem; + } + } + + @Entity( name = "LocalLineItem" ) + @Table( name = "LocalLineItem" ) + public static class LocalLineItem { + @Id + @GeneratedValue + public Integer id; + public String name; + @ManyToOne + @JoinColumn + public LocalOrder order; + @Column( insertable = false, updatable = false ) + public int position; + + public LocalLineItem() { + } + + public LocalLineItem(String name, LocalOrder order) { + this.name = name; + this.order = order; + } + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { LocalOrder.class, LocalLineItem.class }; + } + + @Before + public void before() { + Session s = sessionFactory().openSession(); + s.beginTransaction(); + LocalOrder localOrder = new LocalOrder(); + localOrder.makeLineItem( "Shoes" ); + localOrder.makeLineItem( "Socks" ); + s.save( localOrder ); + s.getTransaction().commit(); + s.close(); + } + + @After + public void after() { + Session s = sessionFactory().openSession(); + s.beginTransaction(); + s.createQuery( "delete LocalLineItem" ).executeUpdate(); + s.createQuery( "delete LocalOrder" ).executeUpdate(); + s.getTransaction().commit(); + s.close(); + } + + @Test + public void testIt() { + { + Session s = openSession(); + s.beginTransaction(); + LocalOrder order = s.byId( LocalOrder.class ).load( 1 ); + assertEquals( 2, order.lineItems.size() ); + LocalLineItem shoes = order.lineItems.get( 0 ); + LocalLineItem socks = order.lineItems.get( 1 ); + assertEquals( "Shoes", shoes.name ); + assertEquals( 0, shoes.position ); + assertEquals( 1, socks.position ); + order.lineItems.remove( socks ); + order.lineItems.add( 0, socks ); + s.getTransaction().commit(); + s.close(); + } + + { + Session s = openSession(); + s.beginTransaction(); + LocalOrder order = s.byId( LocalOrder.class ).load( 1 ); + assertEquals( 2, order.lineItems.size() ); + LocalLineItem socks = order.lineItems.get( 0 ); + LocalLineItem shoes = order.lineItems.get( 1 ); + assertEquals( "Shoes", shoes.name ); + assertEquals( 0, socks.position ); + assertEquals( 1, shoes.position ); + + s.getTransaction().commit(); + s.close(); + } + } +} diff --git a/hibernate-envers/src/test/resources/log4j.properties b/hibernate-envers/src/test/resources/log4j.properties index cf5a95cff3..e516e460d1 100644 --- a/hibernate-envers/src/test/resources/log4j.properties +++ b/hibernate-envers/src/test/resources/log4j.properties @@ -12,9 +12,12 @@ log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n log4j.rootLogger=info, stdout log4j.logger.org.hibernate.test=info -log4j.logger.org.hibernate.tool.hbm2ddl=debug # SQL Logging - HHH-6833 log4j.logger.org.hibernate.SQL=debug +log4j.logger.org.hibernate.tool.hbm2ddl=debug + +log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=trace +log4j.logger.org.hibernate.type.descriptor.sql.BasicExtractor=trace log4j.logger.org.hibernate.envers.boot.internal.AdditionalJaxbMappingProducerImpl=trace \ No newline at end of file