HHH-1268 - Unidirection OneToMany causes duplicate key entry violation when removing from list

Add replicating test case
This commit is contained in:
Romain Fromi 2018-03-28 11:08:43 +02:00 committed by Vlad Mihalcea
parent 84757b12c3
commit b87be0cc25
1 changed files with 173 additions and 0 deletions

View File

@ -0,0 +1,173 @@
/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.mapping;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OrderColumn;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.testing.FailureExpected;
import org.hibernate.testing.TestForIssue;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
@TestForIssue(jiraKey = "HHH-1268")
public class UnidirectionalOneToManyUniqueConstraintOrderColumnTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected void afterEntityManagerFactoryBuilt() {
doInJPA( this::entityManagerFactory, entityManager -> {
ParentData parent = new ParentData();
parent.id = 1L;
entityManager.persist( parent );
String[] childrenStr = new String[] {"One", "Two", "Three"};
for ( String str : childrenStr ) {
ChildData child = new ChildData( str );
parent.getChildren().add( child );
}
} );
}
@Test
@FailureExpected( jiraKey = "HHH-1268" )
public void testRemovingAnElement() {
doInJPA( this::entityManagerFactory, entityManager -> {
ParentData parent = entityManager.find( ParentData.class, 1L );
List<ChildData> children = parent.getChildren();
children.remove( 0 );
} );
}
@Test
@FailureExpected( jiraKey = "HHH-1268" )
public void testAddingAnElement() {
doInJPA( this::entityManagerFactory, entityManager -> {
ParentData parent = entityManager.find( ParentData.class, 1L );
List<ChildData> children = parent.getChildren();
children.add( 1, new ChildData( "Another" ) );
} );
}
@Test
@FailureExpected( jiraKey = "HHH-1268" )
public void testRemovingAndAddingAnElement() {
doInJPA( this::entityManagerFactory, entityManager -> {
ParentData parent = entityManager.find( ParentData.class, 1L );
List<ChildData> children = parent.getChildren();
children.remove( 0 );
children.add( 1, new ChildData( "Another" ) );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
ParentData parent = entityManager.find( ParentData.class, 1L );
List<String> childIds = parent.getChildren()
.stream()
.map( ChildData::toString )
.collect( Collectors.toList() );
int i = 0;
assertEquals( "Two", childIds.get( i++ ));
assertEquals( "Another", childIds.get( i++ ));
assertEquals( "Three", childIds.get( i ));
} );
}
@Test
@FailureExpected( jiraKey = "HHH-1268" )
public void testRemovingOneAndAddingTwoElements() {
doInJPA( this::entityManagerFactory, entityManager -> {
ParentData parent = entityManager.find( ParentData.class, 1L );
List<ChildData> children = parent.getChildren();
children.remove( 0 );
children.add( 1, new ChildData( "Another" ) );
children.add( new ChildData( "Another Another" ) );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
ParentData parent = entityManager.find( ParentData.class, 1L );
List<String> childIds = parent.getChildren()
.stream()
.map( ChildData::toString )
.collect( Collectors.toList() );
int i = 0;
assertEquals( "Two", childIds.get( i++ ) );
assertEquals( "Another", childIds.get( i++ ) );
assertEquals( "Three", childIds.get( i++ ) );
assertEquals( "Another Another", childIds.get( i ) );
} );
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
ParentData.class,
ChildData.class
};
}
@Entity(name = "ParentData")
public static class ParentData {
@Id
long id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "parentId", nullable = false)
@OrderColumn(name = "listOrder")
private List<ChildData> children = new ArrayList<>();
public List<ChildData> getChildren() {
return children;
}
}
@Entity(name = "ChildData")
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "parentId", "listOrder" }) })
public static class ChildData {
@Id
@GeneratedValue
long id;
String childId;
public ChildData() {
}
public ChildData(String id) {
childId = id;
}
@Override
public String toString() {
return childId;
}
}
}