HHH-12607 - Reworked and introduced more test cases.
This commit is contained in:
parent
0b7c1e2fcb
commit
e41e5445f8
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
* 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.collection.embeddable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OrderColumn;
|
||||||
|
import javax.persistence.Tuple;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
|
import org.hibernate.envers.test.Priority;
|
||||||
|
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.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test verifies that when a list-based {@link ElementCollection} of {@link Embeddable} objects
|
||||||
|
* are audited that the same number of audit rows are generated regardless whether the embeddable
|
||||||
|
* implements proper {@code equals} and {@code hashCode} methods.
|
||||||
|
*
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-12607")
|
||||||
|
public class ListEqualsHashCodeTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] { TestEntity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Priority(10)
|
||||||
|
public void initData() {
|
||||||
|
final Emb emb1 = new Emb( "value1" );
|
||||||
|
final Emb emb2 = new Emb( "value2" );
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = new TestEntity( 1 );
|
||||||
|
e.setEmbs1( new ArrayList<>() );
|
||||||
|
e.getEmbs1().add( emb1 );
|
||||||
|
e.getEmbs1().add( emb2 );
|
||||||
|
entityManager.persist( e );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = entityManager.find( TestEntity.class, 1 );
|
||||||
|
for ( Emb emb : e.getEmbs1() ) {
|
||||||
|
if ( emb.getValue().equals( "value1" ) ) {
|
||||||
|
e.getEmbs1().remove( emb );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.getEmbs1().add( new Emb( "value3" ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForValidityAuditStrategy() {
|
||||||
|
if ( ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD WHERE REVEND IS NULL",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 6 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForDefaultAuditStrategy() {
|
||||||
|
if ( !ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 6 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory1() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 1 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertHasEmbeddableWithValue( e, "value1" );
|
||||||
|
assertHasEmbeddableWithValue( e, "value2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory2() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 2 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertHasEmbeddableWithValue( e, "value3" );
|
||||||
|
assertHasEmbeddableWithValue( e, "value2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertHasEmbeddableWithValue(TestEntity entity, String value) {
|
||||||
|
for ( Emb embeddable : entity.getEmbs1() ) {
|
||||||
|
if ( embeddable.getValue().equals( value ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fail( "Failed to find embeddable with value [" + value + "]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity")
|
||||||
|
@Audited
|
||||||
|
public static class TestEntity {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@OrderColumn
|
||||||
|
private List<Emb> embs1;
|
||||||
|
|
||||||
|
public TestEntity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestEntity(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Emb> getEmbs1() {
|
||||||
|
return embs1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmbs1(List<Emb> embs1) {
|
||||||
|
this.embs1 = embs1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Emb implements Serializable {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Emb() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Emb(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Emb emb = (Emb) o;
|
||||||
|
return Objects.equals( value, emb.value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* 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.collection.embeddable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OrderColumn;
|
||||||
|
import javax.persistence.Tuple;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
|
import org.hibernate.envers.test.Priority;
|
||||||
|
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.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test verifies that when a list-based {@link ElementCollection} of {@link Embeddable} objects
|
||||||
|
* are audited that the same number of audit rows are generated regardless whether the embeddable
|
||||||
|
* implements proper {@code equals} and {@code hashCode} methods.
|
||||||
|
*
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-12607")
|
||||||
|
public class ListNoEqualsHashCodeTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] { TestEntity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Priority(10)
|
||||||
|
public void initData() {
|
||||||
|
final Emb emb1 = new Emb( "value1" );
|
||||||
|
final Emb emb2 = new Emb( "value2" );
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = new TestEntity( 1 );
|
||||||
|
e.setEmbs1( new ArrayList<>() );
|
||||||
|
e.getEmbs1().add( emb1 );
|
||||||
|
e.getEmbs1().add( emb2 );
|
||||||
|
entityManager.persist( e );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = entityManager.find( TestEntity.class, 1 );
|
||||||
|
for ( Emb emb : e.getEmbs1() ) {
|
||||||
|
if ( emb.getValue().equals( "value1" ) ) {
|
||||||
|
e.getEmbs1().remove( emb );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.getEmbs1().add( new Emb( "value3" ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForValidityAuditStrategy() {
|
||||||
|
if ( ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD WHERE REVEND IS NULL",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 6 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForDefaultAuditStrategy() {
|
||||||
|
if ( !ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 6 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory1() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 1 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertHasEmbeddableWithValue( e, "value1" );
|
||||||
|
assertHasEmbeddableWithValue( e, "value2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory2() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 2 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertHasEmbeddableWithValue( e, "value3" );
|
||||||
|
assertHasEmbeddableWithValue( e, "value2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertHasEmbeddableWithValue(TestEntity entity, String value) {
|
||||||
|
for ( Emb embeddable : entity.getEmbs1() ) {
|
||||||
|
if ( embeddable.getValue().equals( value ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fail( "Failed to find embeddable with value [" + value + "]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity")
|
||||||
|
@Audited
|
||||||
|
public static class TestEntity {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@OrderColumn
|
||||||
|
private List<Emb> embs1;
|
||||||
|
|
||||||
|
public TestEntity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestEntity(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Emb> getEmbs1() {
|
||||||
|
return embs1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmbs1(List<Emb> embs1) {
|
||||||
|
this.embs1 = embs1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Emb implements Serializable {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Emb() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Emb(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* 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.collection.embeddable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Tuple;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
|
import org.hibernate.envers.test.Priority;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test verifies that when a map-based {@link ElementCollection} of {@link Embeddable} objects
|
||||||
|
* are audited that the same number of audit rows are generated regardless whether the embeddable
|
||||||
|
* implements proper {@code equals} and {@code hashCode} methods.
|
||||||
|
*
|
||||||
|
* The {@link ValidityAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | REVEND | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | 2 | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | null | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | null | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | null | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
*
|
||||||
|
* The {@link org.hibernate.envers.strategy.DefaultAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
*
|
||||||
|
* This test uses hashcode and equals as a baseline.
|
||||||
|
*
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-12607")
|
||||||
|
public class MapEqualsHashCodeTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] { TestEntity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Priority(10)
|
||||||
|
public void initData() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = new TestEntity( 1 );
|
||||||
|
e.setEmbs1( new HashMap<>() );
|
||||||
|
e.getEmbs1().put( "a", new Emb( "value1" ) );
|
||||||
|
e.getEmbs1().put( "b", new Emb( "value2" ) );
|
||||||
|
entityManager.persist( e );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = entityManager.find( TestEntity.class, 1 );
|
||||||
|
e.getEmbs1().put( "a", new Emb( "value3" ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForValidityAuditStrategy() {
|
||||||
|
if ( ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD WHERE REVEND IS NULL",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 3 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForDefaultAuditStrategy() {
|
||||||
|
if ( !ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory1() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 1 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertEquals( "value1", e.getEmbs1().get( "a" ).getValue() );
|
||||||
|
assertEquals( "value2", e.getEmbs1().get( "b" ).getValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory2() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 2 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertEquals( "value3", e.getEmbs1().get( "a" ).getValue() );
|
||||||
|
assertEquals( "value2", e.getEmbs1().get( "b" ).getValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity")
|
||||||
|
@Audited
|
||||||
|
public static class TestEntity {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
private Map<String, Emb> embs1;
|
||||||
|
|
||||||
|
public TestEntity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestEntity(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Emb> getEmbs1() {
|
||||||
|
return embs1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmbs1(Map<String, Emb> embs1) {
|
||||||
|
this.embs1 = embs1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Emb implements Serializable {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Emb() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Emb(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Emb emb = (Emb) o;
|
||||||
|
return Objects.equals( value, emb.value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.envers.test;
|
package org.hibernate.envers.test.integration.collection.embeddable;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
@ -20,7 +20,8 @@ import javax.persistence.Tuple;
|
||||||
|
|
||||||
import org.hibernate.envers.Audited;
|
import org.hibernate.envers.Audited;
|
||||||
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
import org.hibernate.envers.test.tools.TablePrinter;
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
|
import org.hibernate.envers.test.Priority;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
@ -29,10 +30,120 @@ import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* This test verifies that when a map-based {@link ElementCollection} of {@link Embeddable} objects
|
||||||
|
* are audited that the same number of audit rows are generated regardless whether the embeddable
|
||||||
|
* implements proper {@code equals} and {@code hashCode} methods.
|
||||||
|
*
|
||||||
|
* The {@link org.hibernate.envers.strategy.ValidityAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | REVEND | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | 2 | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | null | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | null | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | null | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
*
|
||||||
|
* The {@link org.hibernate.envers.strategy.DefaultAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
*
|
||||||
* @author Chris Cranford
|
* @author Chris Cranford
|
||||||
*/
|
*/
|
||||||
@TestForIssue(jiraKey = "HHH-12607")
|
@TestForIssue(jiraKey = "HHH-12607")
|
||||||
public class ElementCollectionTest extends BaseEnversJPAFunctionalTestCase {
|
public class MapNoEqualsHashCodeTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] { TestEntity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Priority(10)
|
||||||
|
public void initData() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = new TestEntity( 1 );
|
||||||
|
e.setEmbs1( new HashMap<>() );
|
||||||
|
e.getEmbs1().put( "a", new Emb( "value1" ) );
|
||||||
|
e.getEmbs1().put( "b", new Emb( "value2" ) );
|
||||||
|
entityManager.persist( e );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = entityManager.find( TestEntity.class, 1 );
|
||||||
|
e.getEmbs1().put( "a", new Emb( "value3" ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForValidityAuditStrategy() {
|
||||||
|
if ( ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD WHERE REVEND IS NULL",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 3 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForDefaultAuditStrategy() {
|
||||||
|
if ( !ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory1() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 1 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertEquals( "value1", e.getEmbs1().get( "a" ).getValue() );
|
||||||
|
assertEquals( "value2", e.getEmbs1().get( "b" ).getValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory2() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 2 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertEquals( "value3", e.getEmbs1().get( "a" ).getValue() );
|
||||||
|
assertEquals( "value2", e.getEmbs1().get( "b" ).getValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Entity(name = "TestEntity")
|
@Entity(name = "TestEntity")
|
||||||
@Audited
|
@Audited
|
||||||
|
@ -80,101 +191,4 @@ public class ElementCollectionTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Class<?>[] getAnnotatedClasses() {
|
|
||||||
return new Class<?>[] { TestEntity.class };
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Priority(10)
|
|
||||||
public void initData() {
|
|
||||||
System.out.println( "************************************************************ " );
|
|
||||||
System.out.println( "REV1 - Insert 2 rows into collection" );
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
TestEntity e = new TestEntity( 1 );
|
|
||||||
e.setEmbs1( new HashMap<>() );
|
|
||||||
e.getEmbs1().put( "a", new Emb( "value1" ) );
|
|
||||||
e.getEmbs1().put( "b", new Emb( "value2" ) );
|
|
||||||
entityManager.persist( e );
|
|
||||||
} );
|
|
||||||
|
|
||||||
TablePrinter.print( this::entityManagerFactory, "TestEntity_AUD", "TestEntity_embs1_AUD" );
|
|
||||||
|
|
||||||
System.out.println( "************************************************************ " );
|
|
||||||
System.out.println( "REV2 - Replace A with value1 as A with value 3 in collection" );
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
TestEntity e = entityManager.find( TestEntity.class, 1 );
|
|
||||||
e.getEmbs1().put( "a", new Emb( "value3" ) );
|
|
||||||
} );
|
|
||||||
|
|
||||||
// ValidityAuditStrategy
|
|
||||||
// always 4 values when equals/hashCode is implemented
|
|
||||||
// +-----+---------+---------------+-----------+--------+--------+
|
|
||||||
// | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | REVEND | VALUE |
|
|
||||||
// +-----+---------+---------------+-----------+--------+--------+
|
|
||||||
// | 1 | 0 | 1 | a | 2 | value1 |
|
|
||||||
// | 1 | 0 | 1 | b | null | value2 |
|
|
||||||
// | 2 | 0 | 1 | a | null | value3 |
|
|
||||||
// | 2 | 2 | 1 | a | null | value1 |
|
|
||||||
// +-----+---------+---------------+-----------+--------+--------+
|
|
||||||
|
|
||||||
// DefaultAuditStrategy
|
|
||||||
// always 4 values when equals/hashCode is implemented
|
|
||||||
// +-----+---------+---------------+-----------+--------+
|
|
||||||
// | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | VALUE |
|
|
||||||
// +-----+---------+---------------+-----------+--------+
|
|
||||||
// | 1 | 0 | 1 | a | value1 |
|
|
||||||
// | 1 | 0 | 1 | b | value2 |
|
|
||||||
// | 2 | 0 | 1 | a | value3 |
|
|
||||||
// | 2 | 2 | 1 | a | value1 |
|
|
||||||
// +-----+---------+---------------+-----------+--------+
|
|
||||||
|
|
||||||
TablePrinter.print( this::entityManagerFactory, "TestEntity_AUD", "TestEntity_embs1_AUD" );
|
|
||||||
|
|
||||||
if ( ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
|
||||||
System.out.println( "************************************************************ " );
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
List<Tuple> results = entityManager
|
|
||||||
.createNativeQuery( "SELECT COUNT(1) FROM TestEntity_embs1_AUD WHERE REVEND IS NULL", Tuple.class )
|
|
||||||
.getResultList();
|
|
||||||
assertEquals( 1, results.size() );
|
|
||||||
assertEquals( BigInteger.valueOf( 3 ), results.get( 0 ).get( 0 ) );
|
|
||||||
} );
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
List<Tuple> results = entityManager
|
|
||||||
.createNativeQuery( "SELECT COUNT(1) FROM TestEntity_embs1_AUD", Tuple.class )
|
|
||||||
.getResultList();
|
|
||||||
assertEquals( 1, results.size() );
|
|
||||||
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.out.println( "************************************************************ " );
|
|
||||||
doInJPA( this::entityManagerFactory, entityManager -> {
|
|
||||||
List<Tuple> results = entityManager
|
|
||||||
.createNativeQuery( "SELECT COUNT(1) FROM TestEntity_embs1_AUD", Tuple.class )
|
|
||||||
.getResultList();
|
|
||||||
assertEquals( 1, results.size() );
|
|
||||||
|
|
||||||
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRevisionHistory1() {
|
|
||||||
TestEntity e = getAuditReader().find( TestEntity.class, 1, 1 );
|
|
||||||
assertEquals( 2, e.getEmbs1().size() );
|
|
||||||
assertEquals( "value1", e.getEmbs1().get( "a" ).getValue() );
|
|
||||||
assertEquals( "value2", e.getEmbs1().get( "b" ).getValue() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRevisionHistory2() {
|
|
||||||
TestEntity e = getAuditReader().find( TestEntity.class, 1, 2 );
|
|
||||||
assertEquals( 2, e.getEmbs1().size() );
|
|
||||||
assertEquals( "value3", e.getEmbs1().get( "a" ).getValue() );
|
|
||||||
assertEquals( "value2", e.getEmbs1().get( "b" ).getValue() );
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
/*
|
||||||
|
* 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.collection.embeddable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Tuple;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
|
import org.hibernate.envers.test.Priority;
|
||||||
|
import org.hibernate.envers.test.tools.TestTools;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test verifies that when a set-based {@link ElementCollection} of {@link Embeddable} objects
|
||||||
|
* are audited that the same number of audit rows are generated regardless whether the embeddable
|
||||||
|
* implements proper {@code equals} and {@code hashCode} methods.
|
||||||
|
*
|
||||||
|
* The {@link org.hibernate.envers.strategy.ValidityAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | REVEND | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | 2 | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | null | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | null | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | null | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
*
|
||||||
|
* The {@link org.hibernate.envers.strategy.DefaultAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
*
|
||||||
|
* This test uses hashcode and equals as a baseline.
|
||||||
|
*
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-12607")
|
||||||
|
public class SetEqualsHashCodeTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] { TestEntity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Priority(10)
|
||||||
|
public void initData() {
|
||||||
|
final Emb emb1 = new Emb( "value1" );
|
||||||
|
final Emb emb2 = new Emb( "value2" );
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = new TestEntity( 1 );
|
||||||
|
e.setEmbs1( new HashSet<>() );
|
||||||
|
e.getEmbs1().add( emb1 );
|
||||||
|
e.getEmbs1().add( emb2 );
|
||||||
|
entityManager.persist( e );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = entityManager.find( TestEntity.class, 1 );
|
||||||
|
e.getEmbs1().remove( emb1 );
|
||||||
|
e.getEmbs1().add( new Emb( "value3" ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForValidityAuditStrategy() {
|
||||||
|
if ( ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD WHERE REVEND IS NULL",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 3 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForDefaultAuditStrategy() {
|
||||||
|
if ( !ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory1() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 1 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertEquals( e.getEmbs1(), TestTools.makeSet( new Emb( "value1" ), new Emb( "value2" ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory2() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 2 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertEquals( e.getEmbs1(), TestTools.makeSet( new Emb( "value3" ), new Emb( "value2" ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity")
|
||||||
|
@Audited
|
||||||
|
public static class TestEntity {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
private Set<Emb> embs1;
|
||||||
|
|
||||||
|
public TestEntity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestEntity(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Emb> getEmbs1() {
|
||||||
|
return embs1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmbs1(Set<Emb> embs1) {
|
||||||
|
this.embs1 = embs1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Emb implements Serializable {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Emb() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Emb(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
Emb emb = (Emb) o;
|
||||||
|
return Objects.equals( value, emb.value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,213 @@
|
||||||
|
/*
|
||||||
|
* 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.collection.embeddable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.persistence.ElementCollection;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Tuple;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.strategy.ValidityAuditStrategy;
|
||||||
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
|
import org.hibernate.envers.test.Priority;
|
||||||
|
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.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test verifies that when a set-based {@link ElementCollection} of {@link Embeddable} objects
|
||||||
|
* are audited that the same number of audit rows are generated regardless whether the embeddable
|
||||||
|
* implements proper {@code equals} and {@code hashCode} methods.
|
||||||
|
*
|
||||||
|
* The {@link org.hibernate.envers.strategy.ValidityAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | REVEND | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | 2 | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | null | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | null | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | null | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+--------+
|
||||||
|
*
|
||||||
|
* The {@link org.hibernate.envers.strategy.DefaultAuditStrategy} with equals/hashcode.
|
||||||
|
*
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | REV | REVTYPE | TESTENTITY_ID | EMBS1_KEY | VALUE |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
* | 1 | 0 | 1 | a | value1 |
|
||||||
|
* | 1 | 0 | 1 | b | value2 |
|
||||||
|
* | 2 | 0 | 1 | a | value3 |
|
||||||
|
* | 2 | 2 | 1 | a | value1 |
|
||||||
|
* +-----+---------+---------------+-----------+--------+
|
||||||
|
*
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-12607")
|
||||||
|
public class SetNoEqualsHashCodeTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] { TestEntity.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Priority(10)
|
||||||
|
public void initData() {
|
||||||
|
final Emb emb1 = new Emb( "value1" );
|
||||||
|
final Emb emb2 = new Emb( "value2" );
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = new TestEntity( 1 );
|
||||||
|
e.setEmbs1( new HashSet<>() );
|
||||||
|
e.getEmbs1().add( emb1 );
|
||||||
|
e.getEmbs1().add( emb2 );
|
||||||
|
entityManager.persist( e );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
TestEntity e = entityManager.find( TestEntity.class, 1 );
|
||||||
|
for ( Emb emb : e.getEmbs1() ) {
|
||||||
|
if ( emb.getValue().equals( "value1" ) ) {
|
||||||
|
e.getEmbs1().remove( emb );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.getEmbs1().add( new Emb( "value3" ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForValidityAuditStrategy() {
|
||||||
|
if ( ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD WHERE REVEND IS NULL",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 3 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuditRowsForDefaultAuditStrategy() {
|
||||||
|
if ( !ValidityAuditStrategy.class.getName().equals( getAuditStrategy() ) ) {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Tuple> results = entityManager
|
||||||
|
.createNativeQuery(
|
||||||
|
"SELECT COUNT(1) FROM TestEntity_embs1_AUD",
|
||||||
|
Tuple.class
|
||||||
|
)
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 1, results.size() );
|
||||||
|
assertEquals( BigInteger.valueOf( 4 ), results.get( 0 ).get( 0 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory1() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 1 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertHasEmbeddableWithValue( e, "value1" );
|
||||||
|
assertHasEmbeddableWithValue( e, "value2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionHistory2() {
|
||||||
|
TestEntity e = getAuditReader().find( TestEntity.class, 1, 2 );
|
||||||
|
assertEquals( 2, e.getEmbs1().size() );
|
||||||
|
assertHasEmbeddableWithValue( e, "value3" );
|
||||||
|
assertHasEmbeddableWithValue( e, "value2" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertHasEmbeddableWithValue(TestEntity entity, String value) {
|
||||||
|
for ( Emb embeddable : entity.getEmbs1() ) {
|
||||||
|
if ( embeddable.getValue().equals( value ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fail( "Failed to find embeddable with value [" + value + "]" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "TestEntity")
|
||||||
|
@Audited
|
||||||
|
public static class TestEntity {
|
||||||
|
@Id
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
private Set<Emb> embs1;
|
||||||
|
|
||||||
|
public TestEntity() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestEntity(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Emb> getEmbs1() {
|
||||||
|
return embs1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmbs1(Set<Emb> embs1) {
|
||||||
|
this.embs1 = embs1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class Emb implements Serializable {
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
public Emb() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Emb(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue