HHH-7625 - Added test case.
This commit is contained in:
parent
22f23d8da0
commit
c8aa945b6b
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* 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.onetomany.idclass;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
import org.hibernate.envers.RelationTargetAuditMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@Audited
|
||||||
|
@Entity
|
||||||
|
@IdClass(ManyToManyCompositeKey.ManyToManyId.class)
|
||||||
|
public class ManyToManyCompositeKey {
|
||||||
|
@Id
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
private OneToManyOwned oneToMany;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
private ManyToOneOwned manyToOne;
|
||||||
|
|
||||||
|
public ManyToManyCompositeKey() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToManyCompositeKey(OneToManyOwned oneToMany, ManyToOneOwned manyToOne) {
|
||||||
|
this.oneToMany = oneToMany;
|
||||||
|
this.manyToOne = manyToOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OneToManyOwned getOneToMany() {
|
||||||
|
return this.oneToMany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToOneOwned getManyToOne() {
|
||||||
|
return this.manyToOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToManyId getId() {
|
||||||
|
return new ManyToManyId( oneToMany, manyToOne );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 0;
|
||||||
|
result = 31 * result + ( oneToMany != null ? oneToMany.hashCode() : 0 );
|
||||||
|
result = 31 * result + ( manyToOne != null ? manyToOne.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if( this == obj ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if( !( obj instanceof ManyToManyCompositeKey ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ManyToManyCompositeKey m = (ManyToManyCompositeKey) obj;
|
||||||
|
if ( oneToMany != null ? !oneToMany.equals( m.oneToMany ) : m.oneToMany != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( manyToOne != null ? !manyToOne.equals( m.manyToOne ) : m.manyToOne != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ManyToManyCompositeKey(oneToMany = " +
|
||||||
|
oneToMany.toString() +
|
||||||
|
", manyToOne = " +
|
||||||
|
manyToOne.toString() +
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ManyToManyId implements Serializable {
|
||||||
|
private OneToManyOwned oneToMany;
|
||||||
|
|
||||||
|
private ManyToOneOwned manyToOne;
|
||||||
|
|
||||||
|
ManyToManyId() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ManyToManyId(OneToManyOwned oneToMany, ManyToOneOwned manyToOne) {
|
||||||
|
this.oneToMany = oneToMany;
|
||||||
|
this.manyToOne = manyToOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OneToManyOwned getOneToMany() {
|
||||||
|
return this.oneToMany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToOneOwned getManyToOne() {
|
||||||
|
return this.manyToOne;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 3;
|
||||||
|
result = 17 * result + ( oneToMany != null ? oneToMany.hashCode() : 0 );
|
||||||
|
result = 17 * result + ( manyToOne != null ? manyToOne.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if( this == obj ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if( !( obj instanceof ManyToManyId ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ManyToManyId m = (ManyToManyId) obj;
|
||||||
|
if ( oneToMany != null ? !oneToMany.equals( m.oneToMany ) : m.oneToMany != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( manyToOne != null ? !manyToOne.equals( m.manyToOne ) : m.manyToOne != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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.onetomany.idclass;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Audited
|
||||||
|
public class ManyToOneOwned {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
public ManyToOneOwned() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToOneOwned(String data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ManyToOneOwned(Long id, String data) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( !( o instanceof ManyToOneOwned ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ManyToOneOwned that = (ManyToOneOwned) o;
|
||||||
|
if ( data != null ? !data.equals( that.data ) : that.data != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 3;
|
||||||
|
result = 11 * result + ( data != null ? data.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ManyToOneOwned(id = " + id + ", data = " + data + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,152 @@
|
||||||
|
/*
|
||||||
|
* 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.onetomany.idclass;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.hibernate.envers.query.AuditEntity;
|
||||||
|
import org.hibernate.envers.test.BaseEnversJPAFunctionalTestCase;
|
||||||
|
import org.hibernate.envers.test.Priority;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.hibernate.testing.transaction.TransactionUtil;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-7625")
|
||||||
|
public class OneToManyCompositeKeyTest extends BaseEnversJPAFunctionalTestCase {
|
||||||
|
private ManyToManyCompositeKey.ManyToManyId owning1Id = null;
|
||||||
|
private ManyToManyCompositeKey.ManyToManyId owning2Id = null;
|
||||||
|
private Long oneToManyId;
|
||||||
|
private Long manyToOne1Id;
|
||||||
|
private Long manyToOne2Id;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[] { OneToManyOwned.class, ManyToManyCompositeKey.class, ManyToOneOwned.class };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Priority(10)
|
||||||
|
public void initData() {
|
||||||
|
// Revision 1
|
||||||
|
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
OneToManyOwned oneToManyOwned = new OneToManyOwned( "data", null );
|
||||||
|
ManyToOneOwned manyToOneOwned1 = new ManyToOneOwned( "data1" );
|
||||||
|
ManyToOneOwned manyToOneOwned2 = new ManyToOneOwned( "data2" );
|
||||||
|
ManyToManyCompositeKey owning1 = new ManyToManyCompositeKey( oneToManyOwned, manyToOneOwned1 );
|
||||||
|
ManyToManyCompositeKey owning2 = new ManyToManyCompositeKey( oneToManyOwned, manyToOneOwned2 );
|
||||||
|
|
||||||
|
entityManager.persist(oneToManyOwned);
|
||||||
|
entityManager.persist(manyToOneOwned1);
|
||||||
|
entityManager.persist(manyToOneOwned2);
|
||||||
|
entityManager.persist( owning1 );
|
||||||
|
entityManager.persist( owning2 );
|
||||||
|
|
||||||
|
owning1Id = owning1.getId();
|
||||||
|
owning2Id = owning2.getId();
|
||||||
|
|
||||||
|
oneToManyId = oneToManyOwned.getId();
|
||||||
|
manyToOne1Id = manyToOneOwned1.getId();
|
||||||
|
manyToOne2Id = manyToOneOwned2.getId();
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Revision 2
|
||||||
|
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
ManyToManyCompositeKey owning1 = entityManager.find( ManyToManyCompositeKey.class, owning1Id );
|
||||||
|
entityManager.remove( owning1 );
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Revision 3
|
||||||
|
TransactionUtil.doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
ManyToManyCompositeKey owning2 = entityManager.find( ManyToManyCompositeKey.class, owning2Id );
|
||||||
|
entityManager.remove( owning2 );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRevisionsCounts() {
|
||||||
|
assertEquals( Arrays.asList( 1, 2 ), getAuditReader().getRevisions( ManyToManyCompositeKey.class, owning1Id ) );
|
||||||
|
assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( ManyToManyCompositeKey.class, owning2Id ) );
|
||||||
|
assertEquals( Arrays.asList( 1 ), getAuditReader().getRevisions( OneToManyOwned.class, oneToManyId ) );
|
||||||
|
assertEquals( Arrays.asList( 1 ), getAuditReader().getRevisions( ManyToOneOwned.class, manyToOne1Id ) );
|
||||||
|
assertEquals( Arrays.asList( 1 ), getAuditReader().getRevisions( ManyToOneOwned.class, manyToOne2Id ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneToManyHistory() {
|
||||||
|
final OneToManyOwned rev1 = getAuditReader().find( OneToManyOwned.class, oneToManyId, 1 );
|
||||||
|
assertEquals( "data", rev1.getData() );
|
||||||
|
assertEquals( 2, rev1.getManyToManyCompositeKeys().size() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testManyToOne1History() {
|
||||||
|
final ManyToOneOwned rev1 = getAuditReader().find( ManyToOneOwned.class, manyToOne1Id, 1 );
|
||||||
|
assertEquals( "data1", rev1.getData() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testManyToOne2History() {
|
||||||
|
final ManyToOneOwned rev1 = getAuditReader().find( ManyToOneOwned.class, manyToOne2Id, 1 );
|
||||||
|
assertEquals( "data2", rev1.getData() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOwning1History() {
|
||||||
|
// objects
|
||||||
|
final OneToManyOwned oneToMany = new OneToManyOwned( 1L, "data", null );
|
||||||
|
final ManyToOneOwned manyToOne = new ManyToOneOwned( 2L, "data1" );
|
||||||
|
|
||||||
|
// insert revision
|
||||||
|
final ManyToManyCompositeKey rev1 = getAuditReader().find( ManyToManyCompositeKey.class, owning1Id, 1 );
|
||||||
|
assertEquals( rev1.getOneToMany(), oneToMany );
|
||||||
|
assertEquals( rev1.getManyToOne(), manyToOne );
|
||||||
|
|
||||||
|
// removal revision - find returns null for deleted
|
||||||
|
assertNull( getAuditReader().find( ManyToManyCompositeKey.class, owning1Id, 2 ) );
|
||||||
|
|
||||||
|
// fetch revision 2 using 'select deletions' api and verify.
|
||||||
|
final ManyToManyCompositeKey rev2 = (ManyToManyCompositeKey) getAuditReader()
|
||||||
|
.createQuery()
|
||||||
|
.forRevisionsOfEntity( ManyToManyCompositeKey.class, true, true )
|
||||||
|
.add( AuditEntity.id().eq( owning1Id ) )
|
||||||
|
.add( AuditEntity.revisionNumber().eq( 2 ) )
|
||||||
|
.getSingleResult();
|
||||||
|
assertEquals( rev2.getOneToMany(), oneToMany );
|
||||||
|
assertEquals( rev2.getManyToOne(), manyToOne );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOwning2History() {
|
||||||
|
// objects
|
||||||
|
final OneToManyOwned oneToMany = new OneToManyOwned( 1L, "data", null );
|
||||||
|
final ManyToOneOwned manyToOne = new ManyToOneOwned( 3L, "data2" );
|
||||||
|
|
||||||
|
// insert revision
|
||||||
|
final ManyToManyCompositeKey rev1 = getAuditReader().find( ManyToManyCompositeKey.class, owning2Id, 1 );
|
||||||
|
assertEquals( rev1.getOneToMany(), oneToMany );
|
||||||
|
assertEquals( rev1.getManyToOne(), manyToOne );
|
||||||
|
|
||||||
|
// removal revision - find returns null for deleted
|
||||||
|
assertNull( getAuditReader().find( ManyToManyCompositeKey.class, owning2Id, 3 ) );
|
||||||
|
|
||||||
|
// fetch revision 3 using 'select deletions' api and verify.
|
||||||
|
final ManyToManyCompositeKey rev2 = (ManyToManyCompositeKey) getAuditReader()
|
||||||
|
.createQuery()
|
||||||
|
.forRevisionsOfEntity( ManyToManyCompositeKey.class, true, true )
|
||||||
|
.add( AuditEntity.id().eq( owning2Id ) )
|
||||||
|
.add( AuditEntity.revisionNumber().eq( 3 ) )
|
||||||
|
.getSingleResult();
|
||||||
|
assertEquals( rev2.getOneToMany(), oneToMany );
|
||||||
|
assertEquals( rev2.getManyToOne(), manyToOne );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* 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.onetomany.idclass;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.FetchType;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
|
||||||
|
import org.hibernate.envers.Audited;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Chris Cranford
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Audited
|
||||||
|
public class OneToManyOwned {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@OneToMany(fetch = FetchType.LAZY, mappedBy = "oneToMany")
|
||||||
|
private List<ManyToManyCompositeKey> manyToManyCompositeKeys;
|
||||||
|
|
||||||
|
public OneToManyOwned() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public OneToManyOwned(String data, List<ManyToManyCompositeKey> manyToManyCompositeKeys) {
|
||||||
|
this.data = data;
|
||||||
|
this.manyToManyCompositeKeys = manyToManyCompositeKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OneToManyOwned(Long id, String data, List<ManyToManyCompositeKey> manyToManyCompositeKeys) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
this.manyToManyCompositeKeys = manyToManyCompositeKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if ( this == o ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( !( o instanceof OneToManyOwned ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
OneToManyOwned that = (OneToManyOwned) o;
|
||||||
|
if ( data != null ? !data.equals( that.data ) : that.data != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = 3;
|
||||||
|
result = 7 * result + ( data != null ? data.hashCode() : 0 );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OneToManyOwned(id = " + id + ", data = " + data + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ManyToManyCompositeKey> getManyToManyCompositeKeys() {
|
||||||
|
return manyToManyCompositeKeys;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue