Skip to content

Commit

Permalink
HHH-1268 - Unidirection OneToMany causes duplicate key entry violatio…
Browse files Browse the repository at this point in the history
…n when removing from list

Add replicating test case
  • Loading branch information
Romain Fromi authored and vladmihalcea committed Mar 28, 2018
1 parent 84757b1 commit b87be0c
Showing 1 changed file with 173 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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;
}
}

}

0 comments on commit b87be0c

Please sign in to comment.