Extended test cases and provided a fix for the issue

The idea for the fix is to simply stop using properties tag for relations in favor of plain (possibly multiple) propeties
This commit is contained in:
Michal Skowronek 2011-05-25 02:57:55 +02:00
parent 1fa0ac0be0
commit 6f3c564b9a
19 changed files with 223 additions and 131 deletions

View File

@ -86,7 +86,13 @@ public final class ToOneRelationMetadataGenerator {
MetadataTools.prefixNamesInPropertyElement(properties, lastPropertyPrefix, MetadataTools.prefixNamesInPropertyElement(properties, lastPropertyPrefix,
MetadataTools.getColumnNameIterator(value.getColumnIterator()), false, insertable); MetadataTools.getColumnNameIterator(value.getColumnIterator()), false, insertable);
parent.add(properties);
// Extracting related id properties from properties tag
for (Object o : properties.content()) {
Element element = (Element) o;
element.setParent(null);
parent.add(element);
}
// Adding mapper for the id // Adding mapper for the id
PropertyData propertyData = propertyAuditingData.getPropertyData(); PropertyData propertyData = propertyAuditingData.getPropertyData();

View File

@ -22,10 +22,7 @@
* Boston, MA 02110-1301 USA * Boston, MA 02110-1301 USA
*/ */
package org.hibernate.envers.entities.mapper.relation; package org.hibernate.envers.entities.mapper.relation;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.envers.configuration.AuditConfiguration; import org.hibernate.envers.configuration.AuditConfiguration;
@ -40,6 +37,11 @@ import org.hibernate.envers.tools.Tools;
import org.hibernate.envers.tools.reflection.ReflectionTools; import org.hibernate.envers.tools.reflection.ReflectionTools;
import org.hibernate.property.Setter; import org.hibernate.property.Setter;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
* @author Hern<EFBFBD>n Chanfreau * @author Hern<EFBFBD>n Chanfreau
@ -59,13 +61,16 @@ public class ToOneIdMapper implements PropertyMapper {
public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) { public boolean mapToMapFromEntity(SessionImplementor session, Map<String, Object> data, Object newObj, Object oldObj) {
HashMap<String, Object> newData = new HashMap<String, Object>(); HashMap<String, Object> newData = new HashMap<String, Object>();
data.put(propertyData.getName(), newData);
// If this property is originally non-insertable, but made insertable because it is in a many-to-one "fake" // If this property is originally non-insertable, but made insertable because it is in a many-to-one "fake"
// bi-directional relation, we always store the "old", unchaged data, to prevent storing changes made // bi-directional relation, we always store the "old", unchaged data, to prevent storing changes made
// to this field. It is the responsibility of the collection to properly update it if it really changed. // to this field. It is the responsibility of the collection to properly update it if it really changed.
delegate.mapToMapFromEntity(newData, nonInsertableFake ? oldObj : newObj); delegate.mapToMapFromEntity(newData, nonInsertableFake ? oldObj : newObj);
for (Map.Entry<String, Object> entry : newData.entrySet()) {
data.put(entry.getKey(), entry.getValue());
}
//noinspection SimplifiableConditionalExpression //noinspection SimplifiableConditionalExpression
return nonInsertableFake ? false : !Tools.entitiesEqual(session, referencedEntityName, newObj, oldObj); return nonInsertableFake ? false : !Tools.entitiesEqual(session, referencedEntityName, newObj, oldObj);
} }
@ -76,7 +81,8 @@ public class ToOneIdMapper implements PropertyMapper {
return; return;
} }
Object entityId = delegate.mapToIdFromMap((Map) data.get(propertyData.getName())); Object entityId;
entityId = delegate.mapToIdFromMap(data);
Object value; Object value;
if (entityId == null) { if (entityId == null) {
value = null; value = null;

View File

@ -45,7 +45,7 @@ public class NotNullAuditExpression implements AuditCriterion {
if (relatedEntity == null) { if (relatedEntity == null) {
parameters.addNotNullRestriction(propertyName, true); parameters.addNotNullRestriction(propertyName, true);
} else { } else {
relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, null, propertyName, false); relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, null, null, false);
} }
} }
} }

View File

@ -45,7 +45,7 @@ public class NullAuditExpression implements AuditCriterion {
if (relatedEntity == null) { if (relatedEntity == null) {
parameters.addNullRestriction(propertyName, true); parameters.addNullRestriction(propertyName, true);
} else { } else {
relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, null, propertyName, true); relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, null, null, true);
} }
} }
} }

View File

@ -52,7 +52,7 @@ public class RelatedAuditExpression implements AuditCriterion {
throw new AuditException("This criterion can only be used on a property that is " + throw new AuditException("This criterion can only be used on a property that is " +
"a relation to another property."); "a relation to another property.");
} else { } else {
relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, id, propertyName, equals); relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, id, null, equals);
} }
} }
} }

View File

@ -58,7 +58,7 @@ public class SimpleAuditExpression implements AuditCriterion {
Object id = relatedEntity.getIdMapper().mapToIdFromEntity(value); Object id = relatedEntity.getIdMapper().mapToIdFromEntity(value);
relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, id, propertyName, "=".equals(op)); relatedEntity.getIdMapper().addIdEqualsToQuery(parameters, id, null, "=".equals(op));
} }
} }
} }

View File

@ -3,6 +3,7 @@ package org.hibernate.envers.test.integration.inheritance.mixed;
import org.hibernate.envers.test.AbstractSessionTest; import org.hibernate.envers.test.AbstractSessionTest;
import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.Priority;
import org.hibernate.envers.test.integration.inheritance.mixed.entities.Activity; import org.hibernate.envers.test.integration.inheritance.mixed.entities.Activity;
import org.hibernate.envers.test.integration.inheritance.mixed.entities.ActivityId;
import org.hibernate.envers.test.integration.inheritance.mixed.entities.CheckInActivity; import org.hibernate.envers.test.integration.inheritance.mixed.entities.CheckInActivity;
import org.hibernate.envers.test.integration.inheritance.mixed.entities.NormalActivity; import org.hibernate.envers.test.integration.inheritance.mixed.entities.NormalActivity;
import org.junit.Test; import org.junit.Test;
@ -15,11 +16,17 @@ import static org.junit.Assert.assertEquals;
* @author Michal Skowronek (mskowr at o2 pl) * @author Michal Skowronek (mskowr at o2 pl)
*/ */
public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractSessionTest { public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractSessionTest {
private ActivityId id1;
private ActivityId id2;
private ActivityId id3;
@Test @Test
@Priority(10) @Priority(10)
public void initData() { public void initData() {
NormalActivity normalActivity = new NormalActivity(); NormalActivity normalActivity = new NormalActivity();
normalActivity.setId(1); id1 = new ActivityId(1, 2);
normalActivity.setId(id1);
normalActivity.setSequenceNumber(1); normalActivity.setSequenceNumber(1);
// Revision 1 // Revision 1
@ -31,9 +38,10 @@ public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractS
// Revision 2 // Revision 2
getSession().getTransaction().begin(); getSession().getTransaction().begin();
normalActivity = (NormalActivity) getSession().get(NormalActivity.class, 1); normalActivity = (NormalActivity) getSession().get(NormalActivity.class, id1);
CheckInActivity checkInActivity = new CheckInActivity(); CheckInActivity checkInActivity = new CheckInActivity();
checkInActivity.setId(2); id2 = new ActivityId(2, 3);
checkInActivity.setId(id2);
checkInActivity.setSequenceNumber(0); checkInActivity.setSequenceNumber(0);
checkInActivity.setDurationInMinutes(30); checkInActivity.setDurationInMinutes(30);
checkInActivity.setRelatedActivity(normalActivity); checkInActivity.setRelatedActivity(normalActivity);
@ -44,7 +52,8 @@ public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractS
// Revision 3 // Revision 3
normalActivity = new NormalActivity(); normalActivity = new NormalActivity();
normalActivity.setId(3); id3 = new ActivityId(3, 4);
normalActivity.setId(id3);
normalActivity.setSequenceNumber(2); normalActivity.setSequenceNumber(2);
getSession().getTransaction().begin(); getSession().getTransaction().begin();
@ -56,8 +65,8 @@ public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractS
// Revision 4 // Revision 4
getSession().getTransaction().begin(); getSession().getTransaction().begin();
normalActivity = (NormalActivity) getSession().get(NormalActivity.class, 3); normalActivity = (NormalActivity) getSession().get(NormalActivity.class, id3);
checkInActivity = (CheckInActivity) getSession().get(CheckInActivity.class, 2); checkInActivity = (CheckInActivity) getSession().get(CheckInActivity.class, id2);
checkInActivity.setRelatedActivity(normalActivity); checkInActivity.setRelatedActivity(normalActivity);
getSession().merge(checkInActivity); getSession().merge(checkInActivity);
@ -69,18 +78,18 @@ public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractS
@Test @Test
public void testRevisionsCounts() { public void testRevisionsCounts() {
assertEquals(Arrays.asList(1), getAuditReader().getRevisions(NormalActivity.class, 1)); assertEquals(Arrays.asList(1), getAuditReader().getRevisions(NormalActivity.class, id1));
assertEquals(Arrays.asList(3), getAuditReader().getRevisions(NormalActivity.class, 3)); assertEquals(Arrays.asList(3), getAuditReader().getRevisions(NormalActivity.class, id3));
assertEquals(Arrays.asList(2, 4), getAuditReader().getRevisions(CheckInActivity.class, 2)); assertEquals(Arrays.asList(2, 4), getAuditReader().getRevisions(CheckInActivity.class, id2));
} }
@Test @Test
public void testCurrentStateOfCheckInActivity() { public void testCurrentStateOfCheckInActivity() {
final CheckInActivity checkInActivity = (CheckInActivity) getSession().get(CheckInActivity.class, 2); final CheckInActivity checkInActivity = (CheckInActivity) getSession().get(CheckInActivity.class, id2);
final NormalActivity normalActivity = (NormalActivity) getSession().get(NormalActivity.class, 3); final NormalActivity normalActivity = (NormalActivity) getSession().get(NormalActivity.class, id3);
assertEquals(2, checkInActivity.getId().intValue()); assertEquals(id2, checkInActivity.getId());
assertEquals(0, checkInActivity.getSequenceNumber().intValue()); assertEquals(0, checkInActivity.getSequenceNumber().intValue());
assertEquals(30, checkInActivity.getDurationInMinutes().intValue()); assertEquals(30, checkInActivity.getDurationInMinutes().intValue());
final Activity relatedActivity = checkInActivity.getRelatedActivity(); final Activity relatedActivity = checkInActivity.getRelatedActivity();
@ -90,20 +99,20 @@ public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractS
@Test @Test
public void testCheckCurrentStateOfNormalActivities() throws Exception { public void testCheckCurrentStateOfNormalActivities() throws Exception {
final NormalActivity normalActivity1 = (NormalActivity) getSession().get(NormalActivity.class, 1); final NormalActivity normalActivity1 = (NormalActivity) getSession().get(NormalActivity.class, id1);
final NormalActivity normalActivity2 = (NormalActivity) getSession().get(NormalActivity.class, 3); final NormalActivity normalActivity2 = (NormalActivity) getSession().get(NormalActivity.class, id3);
assertEquals(1, normalActivity1.getId().intValue()); assertEquals(id1, normalActivity1.getId());
assertEquals(1, normalActivity1.getSequenceNumber().intValue()); assertEquals(1, normalActivity1.getSequenceNumber().intValue());
assertEquals(3, normalActivity2.getId().intValue()); assertEquals(id3, normalActivity2.getId());
assertEquals(2, normalActivity2.getSequenceNumber().intValue()); assertEquals(2, normalActivity2.getSequenceNumber().intValue());
} }
public void doTestFirstRevisionOfCheckInActivity() throws Exception { public void doTestFirstRevisionOfCheckInActivity() throws Exception {
CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, 2, 2); CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, id2, 2);
NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, 1, 2); NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, id1, 2);
assertEquals(2, checkInActivity.getId().intValue()); assertEquals(id2, checkInActivity.getId());
assertEquals(0, checkInActivity.getSequenceNumber().intValue()); assertEquals(0, checkInActivity.getSequenceNumber().intValue());
assertEquals(30, checkInActivity.getDurationInMinutes().intValue()); assertEquals(30, checkInActivity.getDurationInMinutes().intValue());
Activity relatedActivity = checkInActivity.getRelatedActivity(); Activity relatedActivity = checkInActivity.getRelatedActivity();
@ -112,10 +121,10 @@ public abstract class AbstractInheritanceStrategiesSessionTest extends AbstractS
} }
public void doTestSecondRevisionOfCheckInActivity() throws Exception { public void doTestSecondRevisionOfCheckInActivity() throws Exception {
CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, 2, 4); CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, id2, 4);
NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, 3, 4); NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, id3, 4);
assertEquals(2, checkInActivity.getId().intValue()); assertEquals(id2, checkInActivity.getId());
assertEquals(0, checkInActivity.getSequenceNumber().intValue()); assertEquals(0, checkInActivity.getSequenceNumber().intValue());
assertEquals(30, checkInActivity.getDurationInMinutes().intValue()); assertEquals(30, checkInActivity.getDurationInMinutes().intValue());
Activity relatedActivity = checkInActivity.getRelatedActivity(); Activity relatedActivity = checkInActivity.getRelatedActivity();

View File

@ -14,7 +14,7 @@ public class JoinedSubclassInheritanceSessionTest extends AbstractInheritanceStr
protected void initMappings() throws MappingException, URISyntaxException { protected void initMappings() throws MappingException, URISyntaxException {
URL url = Thread.currentThread().getContextClassLoader().getResource( URL url = Thread.currentThread().getContextClassLoader().getResource(
"mappings/mixedInheritanceStrategies/mappingsPassing.hbm.xml"); "mappings/mixedInheritanceStrategies/mappingsJoinedSubclass.hbm.xml");
config.addFile(new File(url.toURI())); config.addFile(new File(url.toURI()));
} }

View File

@ -4,7 +4,6 @@ import org.hibernate.ejb.Ejb3Configuration;
import org.hibernate.envers.test.AbstractEntityTest; import org.hibernate.envers.test.AbstractEntityTest;
import org.hibernate.envers.test.Priority; import org.hibernate.envers.test.Priority;
import org.hibernate.envers.test.integration.inheritance.mixed.entities.*; import org.hibernate.envers.test.integration.inheritance.mixed.entities.*;
import org.hibernate.testing.FailureExpected;
import org.junit.Test; import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
@ -16,6 +15,10 @@ import static org.junit.Assert.assertEquals;
*/ */
public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest { public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
private ActivityId id2;
private ActivityId id1;
private ActivityId id3;
@Override @Override
public void configure(Ejb3Configuration cfg) { public void configure(Ejb3Configuration cfg) {
cfg.addAnnotatedClass(AbstractActivity.class); cfg.addAnnotatedClass(AbstractActivity.class);
@ -28,7 +31,8 @@ public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
@Priority(10) @Priority(10)
public void initData() { public void initData() {
NormalActivity normalActivity = new NormalActivity(); NormalActivity normalActivity = new NormalActivity();
normalActivity.setId(1); id1 = new ActivityId(1, 2);
normalActivity.setId(id1);
normalActivity.setSequenceNumber(1); normalActivity.setSequenceNumber(1);
// Revision 1 // Revision 1
@ -40,9 +44,10 @@ public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
// Revision 2 // Revision 2
getEntityManager().getTransaction().begin(); getEntityManager().getTransaction().begin();
normalActivity = getEntityManager().find(NormalActivity.class, 1); normalActivity = getEntityManager().find(NormalActivity.class, id1);
CheckInActivity checkInActivity = new CheckInActivity(); CheckInActivity checkInActivity = new CheckInActivity();
checkInActivity.setId(2); id2 = new ActivityId(2, 3);
checkInActivity.setId(id2);
checkInActivity.setSequenceNumber(0); checkInActivity.setSequenceNumber(0);
checkInActivity.setDurationInMinutes(30); checkInActivity.setDurationInMinutes(30);
checkInActivity.setRelatedActivity(normalActivity); checkInActivity.setRelatedActivity(normalActivity);
@ -53,7 +58,8 @@ public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
// Revision 3 // Revision 3
normalActivity = new NormalActivity(); normalActivity = new NormalActivity();
normalActivity.setId(3); id3 = new ActivityId(3, 4);
normalActivity.setId(id3);
normalActivity.setSequenceNumber(2); normalActivity.setSequenceNumber(2);
getEntityManager().getTransaction().begin(); getEntityManager().getTransaction().begin();
@ -65,8 +71,8 @@ public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
// Revision 4 // Revision 4
getEntityManager().getTransaction().begin(); getEntityManager().getTransaction().begin();
normalActivity = getEntityManager().find(NormalActivity.class, 3); normalActivity = getEntityManager().find(NormalActivity.class, id3);
checkInActivity = getEntityManager().find(CheckInActivity.class, 2); checkInActivity = getEntityManager().find(CheckInActivity.class, id2);
checkInActivity.setRelatedActivity(normalActivity); checkInActivity.setRelatedActivity(normalActivity);
getEntityManager().merge(checkInActivity); getEntityManager().merge(checkInActivity);
@ -76,18 +82,18 @@ public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
@Test @Test
public void testRevisionsCounts() { public void testRevisionsCounts() {
assertEquals(Arrays.asList(1), getAuditReader().getRevisions(NormalActivity.class, 1)); assertEquals(Arrays.asList(1), getAuditReader().getRevisions(NormalActivity.class, id1));
assertEquals(Arrays.asList(3), getAuditReader().getRevisions(NormalActivity.class, 3)); assertEquals(Arrays.asList(3), getAuditReader().getRevisions(NormalActivity.class, id3));
assertEquals(Arrays.asList(2, 4), getAuditReader().getRevisions(CheckInActivity.class, 2)); assertEquals(Arrays.asList(2, 4), getAuditReader().getRevisions(CheckInActivity.class, id2));
} }
@Test @Test
public void testCurrentStateOfCheckInActivity() { public void testCurrentStateOfCheckInActivity() {
final CheckInActivity checkInActivity = getEntityManager().find(CheckInActivity.class, 2); final CheckInActivity checkInActivity = getEntityManager().find(CheckInActivity.class, id2);
final NormalActivity normalActivity = getEntityManager().find(NormalActivity.class, 3); final NormalActivity normalActivity = getEntityManager().find(NormalActivity.class, id3);
assertEquals(2, checkInActivity.getId().intValue()); assertEquals(id2, checkInActivity.getId());
assertEquals(0, checkInActivity.getSequenceNumber().intValue()); assertEquals(0, checkInActivity.getSequenceNumber().intValue());
assertEquals(30, checkInActivity.getDurationInMinutes().intValue()); assertEquals(30, checkInActivity.getDurationInMinutes().intValue());
final Activity relatedActivity = checkInActivity.getRelatedActivity(); final Activity relatedActivity = checkInActivity.getRelatedActivity();
@ -97,22 +103,21 @@ public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
@Test @Test
public void testCheckCurrentStateOfNormalActivities() throws Exception { public void testCheckCurrentStateOfNormalActivities() throws Exception {
final NormalActivity normalActivity1 = getEntityManager().find(NormalActivity.class, 1); final NormalActivity normalActivity1 = getEntityManager().find(NormalActivity.class, id1);
final NormalActivity normalActivity2 = getEntityManager().find(NormalActivity.class, 3); final NormalActivity normalActivity2 = getEntityManager().find(NormalActivity.class, id3);
assertEquals(1, normalActivity1.getId().intValue()); assertEquals(id1, normalActivity1.getId());
assertEquals(1, normalActivity1.getSequenceNumber().intValue()); assertEquals(1, normalActivity1.getSequenceNumber().intValue());
assertEquals(3, normalActivity2.getId().intValue()); assertEquals(id3, normalActivity2.getId());
assertEquals(2, normalActivity2.getSequenceNumber().intValue()); assertEquals(2, normalActivity2.getSequenceNumber().intValue());
} }
@Test @Test
@FailureExpected(message = "Problem with mixed inheritance strategies", jiraKey = "HHH-6177")
public void doTestFirstRevisionOfCheckInActivity() throws Exception { public void doTestFirstRevisionOfCheckInActivity() throws Exception {
CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, 2, 2); CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, id2, 2);
NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, 1, 2); NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, id1, 2);
assertEquals(2, checkInActivity.getId().intValue()); assertEquals(id2, checkInActivity.getId());
assertEquals(0, checkInActivity.getSequenceNumber().intValue()); assertEquals(0, checkInActivity.getSequenceNumber().intValue());
assertEquals(30, checkInActivity.getDurationInMinutes().intValue()); assertEquals(30, checkInActivity.getDurationInMinutes().intValue());
Activity relatedActivity = checkInActivity.getRelatedActivity(); Activity relatedActivity = checkInActivity.getRelatedActivity();
@ -121,12 +126,11 @@ public class MixedInheritanceStrategiesEntityTest extends AbstractEntityTest {
} }
@Test @Test
@FailureExpected(message = "Problem with mixed inheritance strategies", jiraKey = "HHH-6177")
public void doTestSecondRevisionOfCheckInActivity() throws Exception { public void doTestSecondRevisionOfCheckInActivity() throws Exception {
CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, 2, 4); CheckInActivity checkInActivity = getAuditReader().find(CheckInActivity.class, id2, 4);
NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, 3, 4); NormalActivity normalActivity = getAuditReader().find(NormalActivity.class, id3, 4);
assertEquals(2, checkInActivity.getId().intValue()); assertEquals(id2, checkInActivity.getId());
assertEquals(0, checkInActivity.getSequenceNumber().intValue()); assertEquals(0, checkInActivity.getSequenceNumber().intValue());
assertEquals(30, checkInActivity.getDurationInMinutes().intValue()); assertEquals(30, checkInActivity.getDurationInMinutes().intValue());
Activity relatedActivity = checkInActivity.getRelatedActivity(); Activity relatedActivity = checkInActivity.getRelatedActivity();

View File

@ -1,7 +1,6 @@
package org.hibernate.envers.test.integration.inheritance.mixed; package org.hibernate.envers.test.integration.inheritance.mixed;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.testing.FailureExpected;
import org.junit.Test; import org.junit.Test;
import java.io.File; import java.io.File;
@ -15,18 +14,16 @@ public class MixedInheritanceStrategiesSessionTest extends AbstractInheritanceSt
protected void initMappings() throws MappingException, URISyntaxException { protected void initMappings() throws MappingException, URISyntaxException {
URL url = Thread.currentThread().getContextClassLoader().getResource( URL url = Thread.currentThread().getContextClassLoader().getResource(
"mappings/mixedInheritanceStrategies/mappingsFailing.hbm.xml"); "mappings/mixedInheritanceStrategies/mappingsMixed.hbm.xml");
config.addFile(new File(url.toURI())); config.addFile(new File(url.toURI()));
} }
@Test @Test
@FailureExpected(message = "Problem with mixed inheritance strategies", jiraKey = "HHH-6177")
public void testFirstRevisionOfCheckInActivity() throws Exception { public void testFirstRevisionOfCheckInActivity() throws Exception {
doTestFirstRevisionOfCheckInActivity(); doTestFirstRevisionOfCheckInActivity();
} }
@Test @Test
@FailureExpected(message = "Problem with mixed inheritance strategies", jiraKey = "HHH-6177")
public void testSecondRevisionOfCheckInActivity() throws Exception { public void testSecondRevisionOfCheckInActivity() throws Exception {
doTestSecondRevisionOfCheckInActivity(); doTestSecondRevisionOfCheckInActivity();
} }

View File

@ -2,8 +2,8 @@ package org.hibernate.envers.test.integration.inheritance.mixed.entities;
import org.hibernate.envers.Audited; import org.hibernate.envers.Audited;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance; import javax.persistence.Inheritance;
import javax.persistence.InheritanceType; import javax.persistence.InheritanceType;
@ -11,15 +11,16 @@ import javax.persistence.InheritanceType;
@Entity @Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class AbstractActivity implements Activity { public abstract class AbstractActivity implements Activity {
@Id @EmbeddedId
private Integer id; private ActivityId id;
private Integer sequenceNumber; private Integer sequenceNumber;
public Integer getId() { public ActivityId getId() {
return id; return id;
} }
public void setId(Integer id) { public void setId(ActivityId id) {
this.id = id; this.id = id;
} }

View File

@ -7,12 +7,15 @@ import javax.persistence.*;
@Audited @Audited
@Entity @Entity
@DiscriminatorValue(value = "CHECK") @DiscriminatorValue(value = "CHECK")
@SecondaryTable(name = "ACTIVITY_CHECK", pkJoinColumns = @PrimaryKeyJoinColumn(name = "ACTIVITY_ID")) @SecondaryTable(name = "ACTIVITY_CHECK",
pkJoinColumns = {@PrimaryKeyJoinColumn(name = "ACTIVITY_ID"),
@PrimaryKeyJoinColumn(name = "ACTIVITY_ID2")})
public abstract class AbstractCheckActivity extends AbstractActivity { public abstract class AbstractCheckActivity extends AbstractActivity {
@Column(table = "ACTIVITY_CHECK") @Column(table = "ACTIVITY_CHECK")
private Integer durationInMinutes; private Integer durationInMinutes;
@ManyToOne(targetEntity = AbstractActivity.class, cascade = CascadeType.MERGE, fetch = FetchType.LAZY) @ManyToOne(targetEntity = AbstractActivity.class, cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
@JoinColumn(table = "ACTIVITY_CHECK") @JoinColumns({@JoinColumn(table = "ACTIVITY_CHECK", referencedColumnName = "id"),
@JoinColumn(table = "ACTIVITY_CHECK", referencedColumnName = "id2")})
private Activity relatedActivity; private Activity relatedActivity;
public Integer getDurationInMinutes() { public Integer getDurationInMinutes() {

View File

@ -1,7 +1,9 @@
package org.hibernate.envers.test.integration.inheritance.mixed.entities; package org.hibernate.envers.test.integration.inheritance.mixed.entities;
public interface Activity { import java.io.Serializable;
Integer getId();
public interface Activity extends Serializable {
ActivityId getId();
Integer getSequenceNumber(); Integer getSequenceNumber();
} }

View File

@ -0,0 +1,53 @@
package org.hibernate.envers.test.integration.inheritance.mixed.entities;
import javax.persistence.Embeddable;
import java.io.Serializable;
@Embeddable
public class ActivityId implements Serializable {
private Integer id;
private Integer id2;
public ActivityId() {
}
public ActivityId(int i, int i1) {
id = i;
id2 = i1;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getId2() {
return id2;
}
public void setId2(Integer id2) {
this.id2 = id2;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return true;
}
if (!(obj instanceof ActivityId)) {
return false;
}
ActivityId id = (ActivityId) obj;
return getId().equals(id.getId()) && getId2().equals(id.getId2());
}
@Override
public int hashCode() {
int result = getId().hashCode();
result = 31 * result + getId2().hashCode();
return result;
}
}

View File

@ -33,6 +33,8 @@ import javax.persistence.EntityManager;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import static junit.framework.Assert.*;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
*/ */
@ -124,14 +126,9 @@ public class JoinNaming extends AbstractEntityTest {
public void testJoinColumnName() { public void testJoinColumnName() {
Iterator<Column> columns = Iterator<Column> columns =
getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.JoinNamingRefIngEntity_AUD") getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.JoinNamingRefIngEntity_AUD")
.getProperty("reference").getColumnIterator(); .getProperty("reference_id").getColumnIterator();
assertTrue(columns.hasNext());
while (columns.hasNext()) { assertEquals("jnree_column_reference", columns.next().getName());
if ("jnree_column_reference".equals(columns.next().getName())) { assertFalse(columns.hasNext());
return;
}
}
assert false;
} }
} }

View File

@ -33,6 +33,8 @@ import javax.persistence.EntityManager;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import static junit.framework.Assert.*;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
*/ */
@ -122,20 +124,16 @@ public class JoinEmbIdNaming extends AbstractEntityTest {
public void testJoinColumnNames() { public void testJoinColumnNames() {
Iterator<Column> columns = Iterator<Column> columns =
getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.ids.JoinEmbIdNamingRefIngEntity_AUD") getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.ids.JoinEmbIdNamingRefIngEntity_AUD")
.getProperty("reference").getColumnIterator(); .getProperty("reference_x").getColumnIterator();
assertTrue(columns.hasNext());
assertEquals("XX_reference", columns.next().getName());
assertFalse(columns.hasNext());
boolean xxFound = false; columns = getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.ids.JoinEmbIdNamingRefIngEntity_AUD")
boolean yyFound = false; .getProperty("reference_y").getColumnIterator();
while (columns.hasNext()) {
if ("XX_reference".equals(columns.next().getName())) {
xxFound = true;
}
if ("YY_reference".equals(columns.next().getName())) { assertTrue(columns.hasNext());
yyFound = true; assertEquals("YY_reference", columns.next().getName());
} assertFalse(columns.hasNext());
}
assert xxFound && yyFound;
} }
} }

View File

@ -33,6 +33,8 @@ import javax.persistence.EntityManager;
import java.util.Arrays; import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import static junit.framework.Assert.*;
/** /**
* @author Adam Warski (adam at warski dot org) * @author Adam Warski (adam at warski dot org)
*/ */
@ -122,20 +124,15 @@ public class JoinMulIdNaming extends AbstractEntityTest {
public void testJoinColumnNames() { public void testJoinColumnNames() {
Iterator<Column> columns = Iterator<Column> columns =
getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.ids.JoinMulIdNamingRefIngEntity_AUD") getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.ids.JoinMulIdNamingRefIngEntity_AUD")
.getProperty("reference").getColumnIterator(); .getProperty("reference_id1").getColumnIterator();
assertTrue(columns.hasNext());
assertEquals("ID1_reference", columns.next().getName());
assertFalse(columns.hasNext());
boolean id1Found = false; columns = getCfg().getClassMapping("org.hibernate.envers.test.integration.naming.ids.JoinMulIdNamingRefIngEntity_AUD")
boolean id2Found = false; .getProperty("reference_id2").getColumnIterator();
while (columns.hasNext()) { assertTrue(columns.hasNext());
if ("ID1_reference".equals(columns.next().getName())) { assertEquals("ID2_reference", columns.next().getName());
id1Found = true; assertFalse(columns.hasNext());
}
if ("ID2_reference".equals(columns.next().getName())) {
id2Found = true;
}
}
assert id1Found && id2Found;
} }
} }

View File

@ -7,15 +7,20 @@
<hibernate-mapping> <hibernate-mapping>
<class abstract="true" name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity" <class abstract="true" name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity"
table="ACTIVITY"> table="ACTIVITY">
<id name="id" type="integer"> <composite-id name="id" class="org.hibernate.envers.test.integration.inheritance.mixed.entities.ActivityId">
<key-property name="id" type="integer"/>
<key-property name="id2" type="integer"/>
<generator class="assigned"/> <generator class="assigned"/>
</id> </composite-id>
<property name="sequenceNumber" type="int" not-null="true"/> <property name="sequenceNumber" type="int" not-null="true"/>
<joined-subclass abstract="true" <joined-subclass abstract="true"
name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractCheckActivity"> name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractCheckActivity">
<key foreign-key="FK_CHKACT_ACT" not-null="true" column="ACTIVITY_ID"/> <key foreign-key="FK_CHKACT_ACT" not-null="true">
<column name="ACTIVITY_ID"/>
<column name="ACTIVITY_ID2"/>
</key>
<property name="durationInMinutes" type="int" not-null="true" column="DURATION_IN_MINUTES"/> <property name="durationInMinutes" type="int" not-null="true" column="DURATION_IN_MINUTES"/>
<many-to-one name="relatedActivity" <many-to-one name="relatedActivity"
cascade="merge" cascade="merge"
@ -23,14 +28,21 @@
class="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity" class="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity"
lazy="proxy"> lazy="proxy">
<column name="RELATED_ACTIVITY_ID" not-null="false"/> <column name="RELATED_ACTIVITY_ID" not-null="false"/>
<column name="RELATED_ACTIVITY_ID2" not-null="false"/>
</many-to-one> </many-to-one>
<joined-subclass name="org.hibernate.envers.test.integration.inheritance.mixed.entities.CheckInActivity"> <joined-subclass name="org.hibernate.envers.test.integration.inheritance.mixed.entities.CheckInActivity">
<key foreign-key="FK_CHKINACT_ACT" not-null="true" column="CHECK_ACTIVITY_ID"/> <key foreign-key="FK_CHKINACT_ACT" not-null="true">
<column name="ACTIVITY_ID"/>
<column name="ACTIVITY_ID2"/>
</key>
</joined-subclass> </joined-subclass>
</joined-subclass> </joined-subclass>
<joined-subclass name="org.hibernate.envers.test.integration.inheritance.mixed.entities.NormalActivity"> <joined-subclass name="org.hibernate.envers.test.integration.inheritance.mixed.entities.NormalActivity">
<key foreign-key="FK_NORMALACT_ACT" not-null="true" column="ACTIVITY_ID"/> <key foreign-key="FK_NORMALACT_ACT" not-null="true">
<column name="ACTIVITY_ID"/>
<column name="ACTIVITY_ID2"/>
</key>
</joined-subclass> </joined-subclass>
</class> </class>

View File

@ -7,9 +7,12 @@
<hibernate-mapping> <hibernate-mapping>
<class abstract="true" name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity" <class abstract="true" name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity"
table="ACTIVITY"> table="ACTIVITY">
<id name="id" type="integer">
<composite-id name="id" class="org.hibernate.envers.test.integration.inheritance.mixed.entities.ActivityId">
<key-property name="id" type="integer"/>
<key-property name="id2" type="integer"/>
<generator class="assigned"/> <generator class="assigned"/>
</id> </composite-id>
<discriminator column="ACTIVITY_TYPE" type="string" length="20"/> <discriminator column="ACTIVITY_TYPE" type="string" length="20"/>
@ -19,7 +22,10 @@
name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractCheckActivity" name="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractCheckActivity"
discriminator-value="CHECK"> discriminator-value="CHECK">
<join table="ACTIVITY_CHECK"> <join table="ACTIVITY_CHECK">
<key foreign-key="FK_CHKACT_ACT" not-null="true" column="ACTIVITY_ID"/> <key foreign-key="FK_CHKACT_ACT" not-null="true">
<column name="ACTIVITY_ID"/>
<column name="ACTIVITY_ID2"/>
</key>
<property name="durationInMinutes" type="int" not-null="true" column="DURATION_IN_MINUTES"/> <property name="durationInMinutes" type="int" not-null="true" column="DURATION_IN_MINUTES"/>
<many-to-one name="relatedActivity" <many-to-one name="relatedActivity"
cascade="merge" cascade="merge"
@ -27,6 +33,7 @@
class="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity" class="org.hibernate.envers.test.integration.inheritance.mixed.entities.AbstractActivity"
lazy="proxy"> lazy="proxy">
<column name="RELATED_ACTIVITY_ID" not-null="false"/> <column name="RELATED_ACTIVITY_ID" not-null="false"/>
<column name="RELATED_ACTIVITY_ID2" not-null="false"/>
</many-to-one> </many-to-one>
</join> </join>
<subclass name="org.hibernate.envers.test.integration.inheritance.mixed.entities.CheckInActivity" <subclass name="org.hibernate.envers.test.integration.inheritance.mixed.entities.CheckInActivity"