HHH-4792:

- fixing the way properties are checked to be mutable
- applying patch to Slawek Garwol - thanks!

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18763 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Adam Warski 2010-02-10 15:30:48 +00:00
parent 09d051150c
commit beebf85e88
6 changed files with 355 additions and 6 deletions

View File

@ -42,7 +42,6 @@ import org.hibernate.MappingException;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.type.ImmutableType;
import org.hibernate.type.Type;
/**
@ -62,7 +61,7 @@ public final class IdMetadataGenerator {
Property property = properties.next();
Type propertyType = property.getType();
if (!"_identifierMapper".equals(property.getName())) {
if (propertyType instanceof ImmutableType) {
if (!propertyType.isMutable()) {
// Last but one parameter: ids are always insertable
mainGenerator.getBasicMetadataGenerator().addBasic(parent,
getIdPersistentPropertyAuditingData(property),

View File

@ -0,0 +1,40 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.envers.test.entities.ids;
/**
* @author Slawek Garwol (slawekgarwol at gmail dot com)
*/
public enum CustomEnum {
YES,
NO;
public String toYesNo() {
return this == YES ? "Y" : "N";
}
public static CustomEnum fromYesNo(String value) {
return "Y".equals(value) ? YES : NO;
}
}

View File

@ -0,0 +1,99 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.envers.test.entities.ids;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
/**
* @author Slawek Garwol (slawekgarwol at gmail dot com)
*/
public class CustomEnumUserType implements UserType {
private static final int[] SQL_TYPES = {Types.VARCHAR};
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class returnedClass() {
return CustomEnum.class;
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
}
if ((x == null) || (y == null)) {
return false;
}
return x.equals(y);
}
public int hashCode(Object x) throws HibernateException {
return (x == null) ? 0 : x.hashCode();
}
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
String name = rs.getString(names[0]);
if (rs.wasNull()) {
return null;
}
return CustomEnum.fromYesNo(name);
}
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
CustomEnum val = (CustomEnum) value;
if (val == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, val.toYesNo());
}
}
public Object deepCopy(Object value) throws HibernateException {
return value;
}
public boolean isMutable() {
return false;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}

View File

@ -0,0 +1,87 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.envers.test.entities.ids;
import java.io.Serializable;
import javax.persistence.Embeddable;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
/**
* @author Slawek Garwol (slawekgarwol at gmail dot com)
*/
@Embeddable
@TypeDef(name = "customEnum", typeClass = CustomEnumUserType.class)
public class EmbIdWithCustomType implements Serializable {
private Integer x;
@Type(type = "customEnum")
private CustomEnum customEnum;
public EmbIdWithCustomType() {
}
public EmbIdWithCustomType(Integer x, CustomEnum customEnum) {
this.x = x;
this.customEnum = customEnum;
}
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
public CustomEnum getCustomEnum() {
return customEnum;
}
public void setCustomEnum(CustomEnum customEnum) {
this.customEnum = customEnum;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof EmbIdWithCustomType)) return false;
EmbIdWithCustomType that = (EmbIdWithCustomType) obj;
if (x != null ? !x.equals(that.x) : that.x != null) return false;
if (customEnum != that.customEnum) return false;
return true;
}
@Override
public int hashCode() {
int result;
result = (x != null ? x.hashCode() : 0);
result = 31 * result + (customEnum != null ? customEnum.hashCode() : 0);
return result;
}
}

View File

@ -0,0 +1,83 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Middleware LLC.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.hibernate.envers.test.entities.ids;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import org.hibernate.envers.Audited;
/**
* @author Slawek Garwol (slawekgarwol at gmail dot com)
*/
@Entity
public class EmbIdWithCustomTypeTestEntity {
@EmbeddedId
private EmbIdWithCustomType id;
@Audited
private String str1;
public EmbIdWithCustomTypeTestEntity() {
}
public EmbIdWithCustomTypeTestEntity(EmbIdWithCustomType id, String str1) {
this.id = id;
this.str1 = str1;
}
public EmbIdWithCustomType getId() {
return id;
}
public void setId(EmbIdWithCustomType id) {
this.id = id;
}
public String getStr1() {
return str1;
}
public void setStr1(String str1) {
this.str1 = str1;
}
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof EmbIdWithCustomTypeTestEntity)) return false;
EmbIdWithCustomTypeTestEntity that = (EmbIdWithCustomTypeTestEntity) obj;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
if (str1 != null ? !str1.equals(that.str1) : that.str1 != null) return false;
return true;
}
public int hashCode() {
int result;
result = (id != null ? id.hashCode() : 0);
result = 31 * result + (str1 != null ? str1.hashCode() : 0);
return result;
}
}

View File

@ -27,10 +27,7 @@ import java.util.Arrays;
import javax.persistence.EntityManager;
import org.hibernate.envers.test.AbstractEntityTest;
import org.hibernate.envers.test.entities.ids.EmbId;
import org.hibernate.envers.test.entities.ids.EmbIdTestEntity;
import org.hibernate.envers.test.entities.ids.MulId;
import org.hibernate.envers.test.entities.ids.MulIdTestEntity;
import org.hibernate.envers.test.entities.ids.*;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@ -44,10 +41,13 @@ public class CompositeIds extends AbstractEntityTest {
private EmbId id2;
private MulId id3;
private MulId id4;
private EmbIdWithCustomType id5;
private EmbIdWithCustomType id6;
public void configure(Ejb3Configuration cfg) {
cfg.addAnnotatedClass(EmbIdTestEntity.class);
cfg.addAnnotatedClass(MulIdTestEntity.class);
cfg.addAnnotatedClass(EmbIdWithCustomTypeTestEntity.class);
}
@BeforeClass(dependsOnMethods = "init")
@ -56,6 +56,8 @@ public class CompositeIds extends AbstractEntityTest {
id2 = new EmbId(10, 20);
id3 = new MulId(100, 101);
id4 = new MulId(102, 103);
id5 = new EmbIdWithCustomType(25, CustomEnum.NO);
id6 = new EmbIdWithCustomType(27, CustomEnum.YES);
// Revision 1
EntityManager em = getEntityManager();
@ -63,6 +65,7 @@ public class CompositeIds extends AbstractEntityTest {
em.persist(new EmbIdTestEntity(id1, "x"));
em.persist(new MulIdTestEntity(id3.getId1(), id3.getId2(), "a"));
em.persist(new EmbIdWithCustomTypeTestEntity(id5, "c"));
em.getTransaction().commit();
@ -72,6 +75,7 @@ public class CompositeIds extends AbstractEntityTest {
em.persist(new EmbIdTestEntity(id2, "y"));
em.persist(new MulIdTestEntity(id4.getId1(), id4.getId2(), "b"));
em.persist(new EmbIdWithCustomTypeTestEntity(id6, "d"));
em.getTransaction().commit();
@ -83,11 +87,15 @@ public class CompositeIds extends AbstractEntityTest {
EmbIdTestEntity ete2 = em.find(EmbIdTestEntity.class, id2);
MulIdTestEntity mte3 = em.find(MulIdTestEntity.class, id3);
MulIdTestEntity mte4 = em.find(MulIdTestEntity.class, id4);
EmbIdWithCustomTypeTestEntity cte5 = em.find(EmbIdWithCustomTypeTestEntity.class, id5);
EmbIdWithCustomTypeTestEntity cte6 = em.find(EmbIdWithCustomTypeTestEntity.class, id6);
ete1.setStr1("x2");
ete2.setStr1("y2");
mte3.setStr1("a2");
mte4.setStr1("b2");
cte5.setStr1("c2");
cte6.setStr1("d2");
em.getTransaction().commit();
@ -98,11 +106,15 @@ public class CompositeIds extends AbstractEntityTest {
ete1 = em.find(EmbIdTestEntity.class, id1);
ete2 = em.find(EmbIdTestEntity.class, id2);
mte3 = em.find(MulIdTestEntity.class, id3);
cte5 = em.find(EmbIdWithCustomTypeTestEntity.class, id5);
cte6 = em.find(EmbIdWithCustomTypeTestEntity.class, id6);
em.remove(ete1);
em.remove(mte3);
em.remove(cte6);
ete2.setStr1("y3");
cte5.setStr1("c3");
em.getTransaction().commit();
@ -126,6 +138,10 @@ public class CompositeIds extends AbstractEntityTest {
assert Arrays.asList(1, 3, 4).equals(getAuditReader().getRevisions(MulIdTestEntity.class, id3));
assert Arrays.asList(2, 3).equals(getAuditReader().getRevisions(MulIdTestEntity.class, id4));
assert Arrays.asList(1, 3, 4).equals(getAuditReader().getRevisions(EmbIdWithCustomTypeTestEntity.class, id5));
assert Arrays.asList(2, 3, 4).equals(getAuditReader().getRevisions(EmbIdWithCustomTypeTestEntity.class, id6));
}
@Test
@ -176,4 +192,29 @@ public class CompositeIds extends AbstractEntityTest {
assert getAuditReader().find(MulIdTestEntity.class, id4, 4).equals(ver2);
assert getAuditReader().find(MulIdTestEntity.class, id4, 5).equals(ver2);
}
@Test
public void testHistoryOfId5() {
EmbIdWithCustomTypeTestEntity ver1 = new EmbIdWithCustomTypeTestEntity(id5, "c");
EmbIdWithCustomTypeTestEntity ver2 = new EmbIdWithCustomTypeTestEntity(id5, "c2");
EmbIdWithCustomTypeTestEntity ver3 = new EmbIdWithCustomTypeTestEntity(id5, "c3");
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id5, 1).equals(ver1);
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id5, 2).equals(ver1);
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id5, 3).equals(ver2);
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id5, 4).equals(ver3);
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id5, 5).equals(ver3);
}
@Test
public void testHistoryOfId6() {
EmbIdWithCustomTypeTestEntity ver1 = new EmbIdWithCustomTypeTestEntity(id6, "d");
EmbIdWithCustomTypeTestEntity ver2 = new EmbIdWithCustomTypeTestEntity(id6, "d2");
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id6, 1) == null;
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id6, 2).equals(ver1);
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id6, 3).equals(ver2);
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id6, 4) == null;
assert getAuditReader().find(EmbIdWithCustomTypeTestEntity.class, id6, 5) == null;
}
}