HHH-12992 - Added test cases.
This commit is contained in:
parent
10148324d1
commit
334e064272
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* 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.envers.test.integration.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.OrderBy;
|
||||
|
||||
import org.hibernate.annotations.BatchSize;
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.envers.AuditMappedBy;
|
||||
import org.hibernate.envers.Audited;
|
||||
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test the use of the {@link OrderBy} annotation on a one-to-many collection where
|
||||
* both sides of the association are audited.
|
||||
*
|
||||
* This mapping invokes the use of the OneAuditEntityQueryGenerator which we want to
|
||||
* verify orders the collection results properly.
|
||||
*
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-12992")
|
||||
public class OrderByOneAuditEntityTest extends BaseEnversJPAFunctionalTestCase {
|
||||
@Entity(name = "Parent")
|
||||
@Audited
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
|
||||
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
|
||||
@OrderBy("index, index2 desc")
|
||||
@AuditMappedBy(mappedBy = "parent", positionMappedBy = "index")
|
||||
@Fetch(FetchMode.SELECT)
|
||||
@BatchSize(size = 100)
|
||||
private List<Child> children = new ArrayList<>();
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Child> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
@Audited
|
||||
public static class Child {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
private Integer index;
|
||||
private Integer index2;
|
||||
|
||||
@ManyToOne
|
||||
private Parent parent;
|
||||
|
||||
public Child() {
|
||||
|
||||
}
|
||||
|
||||
public Child(Integer id, Integer index) {
|
||||
this.id = id;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(Integer index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Integer getIndex2() {
|
||||
return index2;
|
||||
}
|
||||
|
||||
public void setIndex2(Integer index2) {
|
||||
this.index2 = index2;
|
||||
}
|
||||
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
Child child = (Child) o;
|
||||
return Objects.equals( id, child.id ) &&
|
||||
Objects.equals( index, child.index );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( id, index );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Child{" +
|
||||
"id=" + id +
|
||||
", index=" + index +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Parent.class, Child.class };
|
||||
}
|
||||
|
||||
private Integer parentId;
|
||||
|
||||
@Test
|
||||
public void initData() {
|
||||
// Rev 1
|
||||
this.parentId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = new Parent();
|
||||
|
||||
final Child child1 = new Child();
|
||||
child1.setId( 1 );
|
||||
child1.setIndex( 1 );
|
||||
child1.setIndex2( 1 );
|
||||
child1.setParent( parent );
|
||||
parent.getChildren().add( child1 );
|
||||
|
||||
final Child child2 = new Child();
|
||||
child2.setId( 2 );
|
||||
child2.setIndex( 2 );
|
||||
child2.setIndex2( 2 );
|
||||
child2.setParent( parent );
|
||||
parent.getChildren().add( child2 );
|
||||
|
||||
entityManager.persist( parent );
|
||||
|
||||
return parent.getId();
|
||||
} );
|
||||
|
||||
// Rev 2
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
|
||||
final Child child = new Child();
|
||||
child.setId( 3 );
|
||||
child.setIndex( 3 );
|
||||
child.setIndex2( 3 );
|
||||
child.setParent( parent );
|
||||
parent.getChildren().add( child );
|
||||
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
|
||||
// Rev 3
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
parent.getChildren().removeIf( c -> c.getIndex() == 2 );
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
|
||||
// Rev 4
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
parent.getChildren().clear();
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevisionCounts() {
|
||||
assertEquals( Arrays.asList( 1, 2, 3, 4 ), getAuditReader().getRevisions( Parent.class, this.parentId ) );
|
||||
assertEquals( Arrays.asList( 1, 4 ), getAuditReader().getRevisions( Child.class, 1 ) );
|
||||
assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( Child.class, 2 ) );
|
||||
assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( Child.class, 3 ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision1History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 1 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 2, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 2, 2 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision2History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 2 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 3, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 2, 2 ), new Child( 3, 3 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision3History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 3 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 2, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 3, 3 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision4History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 4 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( parent.getChildren().isEmpty() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,343 @@
|
|||
/*
|
||||
* 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.envers.test.integration.query;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OrderBy;
|
||||
|
||||
import org.hibernate.envers.Audited;
|
||||
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test the use of the {@link OrderBy} annotation on a map-based element-collection
|
||||
* that uses entities for the key and value.
|
||||
*
|
||||
* This mapping and association invokes the use of the ThreeEntityQueryGenerator which
|
||||
* we want to verify orders the collection results properly.
|
||||
*
|
||||
* It's worth noting that a mapping like this orders the collection based on the value
|
||||
* and not the key.
|
||||
*
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-12992")
|
||||
public class OrderByThreeEntityTest extends BaseEnversJPAFunctionalTestCase {
|
||||
@Entity(name = "Container")
|
||||
@Audited
|
||||
public static class Container {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
@ElementCollection
|
||||
@OrderBy("value desc")
|
||||
private Map<Key, Item> data = new HashMap<>();
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Map<Key, Item> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Map<Key, Item> data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Key")
|
||||
@Audited
|
||||
public static class Key {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String value;
|
||||
|
||||
public Key() {
|
||||
|
||||
}
|
||||
|
||||
public Key(Integer id, String value) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
Key key = (Key) o;
|
||||
return Objects.equals( id, key.id ) &&
|
||||
Objects.equals( value, key.value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( id, value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Key{" +
|
||||
"id=" + id +
|
||||
", value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Item")
|
||||
@Audited
|
||||
public static class Item {
|
||||
@Id
|
||||
private Integer id;
|
||||
private String value;
|
||||
|
||||
public Item() {
|
||||
|
||||
}
|
||||
|
||||
public Item(Integer id, String value) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
Item item = (Item) o;
|
||||
return Objects.equals( id, item.id ) &&
|
||||
Objects.equals( value, item.value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( id, value );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Item{" +
|
||||
"id=" + id +
|
||||
", value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Container.class, Key.class, Item.class };
|
||||
}
|
||||
|
||||
private Integer containerId;
|
||||
|
||||
@Test
|
||||
public void initData() {
|
||||
// Rev 1
|
||||
this.containerId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Container container = new Container();
|
||||
|
||||
final Key key1 = new Key( 1, "A" );
|
||||
final Key key2 = new Key( 2, "B" );
|
||||
|
||||
final Item item1 = new Item( 1, "I1" );
|
||||
final Item item2 = new Item( 2, "I2" );
|
||||
|
||||
entityManager.persist( item1 );
|
||||
entityManager.persist( item2 );
|
||||
entityManager.persist( key1 );
|
||||
entityManager.persist( key2 );
|
||||
|
||||
container.getData().put( key1, item2 );
|
||||
container.getData().put( key2, item1 );
|
||||
entityManager.persist( container );
|
||||
|
||||
return container.getId();
|
||||
} );
|
||||
|
||||
// Rev 2
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Container container = entityManager.find( Container.class, containerId );
|
||||
|
||||
final Key key = new Key( 3, "C" );
|
||||
final Item item = new Item( 3, "I3" );
|
||||
|
||||
entityManager.persist( key );
|
||||
entityManager.persist( item );
|
||||
|
||||
container.getData().put( key, item );
|
||||
entityManager.merge( container );
|
||||
} );
|
||||
|
||||
// Rev 3
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Container container = entityManager.find( Container.class, containerId );
|
||||
container.getData().keySet().forEach(
|
||||
key -> {
|
||||
if ( "B".equals( key.getValue() ) ) {
|
||||
final Item item = container.getData().get( key );
|
||||
container.getData().remove( key );
|
||||
entityManager.remove( key );
|
||||
entityManager.remove( item );
|
||||
}
|
||||
}
|
||||
);
|
||||
entityManager.merge( container );
|
||||
} );
|
||||
|
||||
// Rev 4
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Container container = entityManager.find( Container.class, containerId );
|
||||
container.getData().entrySet().forEach(
|
||||
entry -> {
|
||||
entityManager.remove( entry.getKey() );
|
||||
entityManager.remove( entry.getValue() );
|
||||
}
|
||||
);
|
||||
container.getData().clear();
|
||||
entityManager.merge( container );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevisionCounts() {
|
||||
assertEquals( Arrays.asList( 1, 2, 3, 4 ), getAuditReader().getRevisions( Container.class, this.containerId ) );
|
||||
|
||||
assertEquals( Arrays.asList( 1, 4 ), getAuditReader().getRevisions( Key.class, 1 ) );
|
||||
assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( Key.class, 2 ) );
|
||||
assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( Key.class, 3 ) );
|
||||
|
||||
assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( Item.class, 1 ) );
|
||||
assertEquals( Arrays.asList( 1, 4 ), getAuditReader().getRevisions( Item.class, 2 ) );
|
||||
assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( Item.class, 3 ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision1History() {
|
||||
final Container container = getAuditReader().find( Container.class, this.containerId, 1 );
|
||||
assertNotNull( container );
|
||||
assertTrue( !container.getData().isEmpty() );
|
||||
assertEquals( 2, container.getData().size() );
|
||||
|
||||
final Iterator<Map.Entry<Key, Item>> iterator = container.getData().entrySet().iterator();
|
||||
|
||||
final Map.Entry<Key, Item> first = iterator.next();
|
||||
assertEquals( new Key( 1, "A" ), first.getKey() );
|
||||
assertEquals( new Item( 2, "I2" ), first.getValue() );
|
||||
|
||||
final Map.Entry<Key, Item> second = iterator.next();
|
||||
assertEquals( new Key( 2, "B" ), second.getKey() );
|
||||
assertEquals( new Item( 1, "I1" ), second.getValue() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision2History() {
|
||||
final Container container = getAuditReader().find( Container.class, this.containerId, 2 );
|
||||
assertNotNull( container );
|
||||
assertTrue( !container.getData().isEmpty() );
|
||||
assertEquals( 3, container.getData().size() );
|
||||
|
||||
final Iterator<Map.Entry<Key, Item>> iterator = container.getData().entrySet().iterator();
|
||||
|
||||
final Map.Entry<Key, Item> first = iterator.next();
|
||||
assertEquals( new Key( 3, "C" ), first.getKey() );
|
||||
assertEquals( new Item( 3, "I3" ), first.getValue() );
|
||||
|
||||
final Map.Entry<Key, Item> second = iterator.next();
|
||||
assertEquals( new Key( 1, "A" ), second.getKey() );
|
||||
assertEquals( new Item( 2, "I2" ), second.getValue() );
|
||||
|
||||
final Map.Entry<Key, Item> third = iterator.next();
|
||||
assertEquals( new Key( 2, "B" ), third.getKey() );
|
||||
assertEquals( new Item( 1, "I1" ), third.getValue() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision3History() {
|
||||
final Container container = getAuditReader().find( Container.class, this.containerId, 3 );
|
||||
assertNotNull( container );
|
||||
assertTrue( !container.getData().isEmpty() );
|
||||
assertEquals( 2, container.getData().size() );
|
||||
|
||||
final Iterator<Map.Entry<Key, Item>> iterator = container.getData().entrySet().iterator();
|
||||
|
||||
final Map.Entry<Key, Item> first = iterator.next();
|
||||
assertEquals( new Key( 3, "C" ), first.getKey() );
|
||||
assertEquals( new Item( 3, "I3" ), first.getValue() );
|
||||
|
||||
final Map.Entry<Key, Item> second = iterator.next();
|
||||
assertEquals( new Key( 1, "A" ), second.getKey() );
|
||||
assertEquals( new Item( 2, "I2" ), second.getValue() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision4History() {
|
||||
final Container container = getAuditReader().find( Container.class, this.containerId, 4 );
|
||||
assertNotNull( container );
|
||||
assertTrue( container.getData().isEmpty() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* 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.envers.test.integration.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.OrderBy;
|
||||
|
||||
import org.hibernate.annotations.BatchSize;
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.envers.Audited;
|
||||
import org.hibernate.envers.RelationTargetAuditMode;
|
||||
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test the use of the {@link OrderBy} annotation on a many-to-many collection
|
||||
* where the two entities are audited but the association is not.
|
||||
*
|
||||
* The double audited entity but no association audited mapping invokes the use
|
||||
* of the TwoEntityOneAuditedGenerator which we want to verify orders the
|
||||
* collection results properly.
|
||||
*
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-12992")
|
||||
public class OrderByTwoEntityOneAuditedTest extends BaseEnversJPAFunctionalTestCase {
|
||||
@Entity(name = "Parent")
|
||||
@Audited
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
|
||||
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
|
||||
@ManyToMany(mappedBy = "parents", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@OrderBy("index, index2 desc")
|
||||
@Fetch(FetchMode.SELECT)
|
||||
@BatchSize(size = 100)
|
||||
private List<Child> children = new ArrayList<>();
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Child> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
@Audited
|
||||
public static class Child {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
private Integer index;
|
||||
private Integer index2;
|
||||
|
||||
@ManyToMany
|
||||
private List<Parent> parents = new ArrayList<>();
|
||||
|
||||
public Child() {
|
||||
|
||||
}
|
||||
|
||||
public Child(Integer id, Integer index) {
|
||||
this.id = id;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(Integer index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Integer getIndex2() {
|
||||
return index2;
|
||||
}
|
||||
|
||||
public void setIndex2(Integer index2) {
|
||||
this.index2 = index2;
|
||||
}
|
||||
|
||||
public List<Parent> getParents() {
|
||||
return parents;
|
||||
}
|
||||
|
||||
public void setParents(List<Parent> parents) {
|
||||
this.parents = parents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
Child child = (Child) o;
|
||||
return Objects.equals( id, child.id ) &&
|
||||
Objects.equals( index, child.index );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( id, index );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Child{" +
|
||||
"id=" + id +
|
||||
", index=" + index +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Parent.class, Child.class };
|
||||
}
|
||||
|
||||
private Integer parentId;
|
||||
|
||||
@Test
|
||||
public void initData() {
|
||||
// Rev 1
|
||||
this.parentId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = new Parent();
|
||||
|
||||
final Child child1 = new Child();
|
||||
child1.setId( 1 );
|
||||
child1.setIndex( 1 );
|
||||
child1.setIndex2( 1 );
|
||||
child1.getParents().add( parent );
|
||||
parent.getChildren().add( child1 );
|
||||
|
||||
final Child child2 = new Child();
|
||||
child2.setId( 2 );
|
||||
child2.setIndex( 2 );
|
||||
child2.setIndex2( 2 );
|
||||
child2.getParents().add( parent );
|
||||
parent.getChildren().add( child2 );
|
||||
|
||||
entityManager.persist( parent );
|
||||
|
||||
return parent.getId();
|
||||
} );
|
||||
|
||||
// Rev 2
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
|
||||
final Child child = new Child();
|
||||
child.setId( 3 );
|
||||
child.setIndex( 3 );
|
||||
child.setIndex2( 3 );
|
||||
child.getParents().add( parent );
|
||||
parent.getChildren().add( child );
|
||||
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
|
||||
// Rev 3
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
parent.getChildren().removeIf( c -> {
|
||||
if ( c.getIndex() == 2 ) {
|
||||
c.getParents().remove( parent );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
|
||||
// Rev 4
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
parent.getChildren().forEach( c -> c.getParents().clear() );
|
||||
parent.getChildren().clear();
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevisionCounts() {
|
||||
assertEquals( Arrays.asList( 1, 2, 3, 4 ), getAuditReader().getRevisions( Parent.class, this.parentId ) );
|
||||
assertEquals( Arrays.asList( 1, 4 ), getAuditReader().getRevisions( Child.class, 1 ) );
|
||||
assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( Child.class, 2 ) );
|
||||
assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( Child.class, 3 ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision1History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 1 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 2, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 2, 2 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision2History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 2 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 3, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 2, 2 ), new Child( 3, 3 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision3History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 3 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 2, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 3, 3 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision4History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 4 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( parent.getChildren().isEmpty() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* 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.envers.test.integration.query;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.OrderBy;
|
||||
|
||||
import org.hibernate.annotations.BatchSize;
|
||||
import org.hibernate.annotations.Fetch;
|
||||
import org.hibernate.annotations.FetchMode;
|
||||
import org.hibernate.envers.AuditMappedBy;
|
||||
import org.hibernate.envers.Audited;
|
||||
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test the use of the {@link OrderBy} annotation on a many-to-many collection
|
||||
* where the two entities and the association are audited.
|
||||
*
|
||||
* The double auditd entity and association mapping invokes the use of the
|
||||
* TwoEntityQueryGenerator which we want to verify orders the collection
|
||||
* results properly.
|
||||
*
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@TestForIssue(jiraKey = "HHH-12992")
|
||||
public class OrderByTwoEntityTest extends BaseEnversJPAFunctionalTestCase {
|
||||
@Entity(name = "Parent")
|
||||
@Audited
|
||||
public static class Parent {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Integer id;
|
||||
|
||||
@ManyToMany(mappedBy = "parents", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||
@OrderBy("index, index2 desc")
|
||||
@AuditMappedBy(mappedBy = "parents", positionMappedBy = "index")
|
||||
@Fetch(FetchMode.SELECT)
|
||||
@BatchSize(size = 100)
|
||||
private List<Child> children = new ArrayList<>();
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public List<Child> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<Child> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
@Audited
|
||||
public static class Child {
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
private Integer index;
|
||||
private Integer index2;
|
||||
|
||||
@ManyToMany
|
||||
private List<Parent> parents = new ArrayList<>();
|
||||
|
||||
public Child() {
|
||||
|
||||
}
|
||||
|
||||
public Child(Integer id, Integer index) {
|
||||
this.id = id;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(Integer index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Integer getIndex2() {
|
||||
return index2;
|
||||
}
|
||||
|
||||
public void setIndex2(Integer index2) {
|
||||
this.index2 = index2;
|
||||
}
|
||||
|
||||
public List<Parent> getParents() {
|
||||
return parents;
|
||||
}
|
||||
|
||||
public void setParents(List<Parent> parents) {
|
||||
this.parents = parents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
Child child = (Child) o;
|
||||
return Objects.equals( id, child.id ) &&
|
||||
Objects.equals( index, child.index );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash( id, index );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Child{" +
|
||||
"id=" + id +
|
||||
", index=" + index +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Parent.class, Child.class };
|
||||
}
|
||||
|
||||
private Integer parentId;
|
||||
|
||||
@Test
|
||||
public void initData() {
|
||||
// Rev 1
|
||||
this.parentId = doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = new Parent();
|
||||
|
||||
final Child child1 = new Child();
|
||||
child1.setId( 1 );
|
||||
child1.setIndex( 1 );
|
||||
child1.setIndex2( 1 );
|
||||
child1.getParents().add( parent );
|
||||
parent.getChildren().add( child1 );
|
||||
|
||||
final Child child2 = new Child();
|
||||
child2.setId( 2 );
|
||||
child2.setIndex( 2 );
|
||||
child2.setIndex2( 2 );
|
||||
child2.getParents().add( parent );
|
||||
parent.getChildren().add( child2 );
|
||||
|
||||
entityManager.persist( parent );
|
||||
|
||||
return parent.getId();
|
||||
} );
|
||||
|
||||
// Rev 2
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
|
||||
final Child child = new Child();
|
||||
child.setId( 3 );
|
||||
child.setIndex( 3 );
|
||||
child.setIndex2( 3 );
|
||||
child.getParents().add( parent );
|
||||
parent.getChildren().add( child );
|
||||
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
|
||||
// Rev 3
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
parent.getChildren().removeIf( c -> {
|
||||
if ( c.getIndex() == 2 ) {
|
||||
c.getParents().remove( parent );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
|
||||
// Rev 4
|
||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||
final Parent parent = entityManager.find( Parent.class, parentId );
|
||||
parent.getChildren().forEach( c -> c.getParents().clear() );
|
||||
parent.getChildren().clear();
|
||||
entityManager.merge( parent );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevisionCounts() {
|
||||
assertEquals( Arrays.asList( 1, 2, 3, 4 ), getAuditReader().getRevisions( Parent.class, this.parentId ) );
|
||||
assertEquals( Arrays.asList( 1, 4 ), getAuditReader().getRevisions( Child.class, 1 ) );
|
||||
assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( Child.class, 2 ) );
|
||||
assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( Child.class, 3 ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision1History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 1 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 2, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 2, 2 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision2History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 2 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 3, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 2, 2 ), new Child( 3, 3 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision3History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 3 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( !parent.getChildren().isEmpty() );
|
||||
assertEquals( 2, parent.getChildren().size() );
|
||||
assertEquals( Arrays.asList( new Child( 1, 1 ), new Child( 3, 3 ) ), parent.getChildren() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevision4History() {
|
||||
final Parent parent = getAuditReader().find( Parent.class, this.parentId, 4 );
|
||||
assertNotNull( parent );
|
||||
assertTrue( parent.getChildren().isEmpty() );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue