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:
parent
09d051150c
commit
beebf85e88
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue