HHH-7645 - Enum property defined within orm.xml using enum-type string does not work

This commit is contained in:
Steve Ebersole 2012-11-06 11:21:38 -06:00
parent 432dab3465
commit 4294e0faee
12 changed files with 412 additions and 24 deletions

View File

@ -612,6 +612,7 @@ public class SimpleValueBinder {
parameters.put( DynamicParameterizedType.IS_PRIMARY_KEY, Boolean.toString( key ) );
parameters.put( DynamicParameterizedType.ENTITY, persistentClassName );
parameters.put( DynamicParameterizedType.XPROPERTY, xproperty );
parameters.put( DynamicParameterizedType.PROPERTY, xproperty.getName() );
parameters.put( DynamicParameterizedType.ACCESS_TYPE, accessType.getType() );
simpleValue.setTypeParameters( parameters );

View File

@ -23,9 +23,8 @@
*/
package org.hibernate.mapping;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import javax.persistence.AttributeConverter;
import java.lang.annotation.Annotation;
import java.lang.reflect.TypeVariable;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
@ -40,7 +39,7 @@ import org.jboss.logging.Logger;
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
import org.hibernate.cfg.AccessType;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.cfg.AttributeConverterDefinition;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.Mappings;
@ -51,7 +50,6 @@ import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.factory.IdentifierGeneratorFactory;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.property.DirectPropertyAccessor;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.ValueBinder;
@ -527,29 +525,23 @@ public class SimpleValue implements KeyValue {
columnsNames[i] = ( (Column) columns.get( i ) ).getName();
}
AccessType accessType = AccessType.getAccessStrategy( typeParameters
.getProperty( DynamicParameterizedType.ACCESS_TYPE ) );
final Class classEntity = ReflectHelper.classForName( typeParameters
.getProperty( DynamicParameterizedType.ENTITY ) );
final String propertyName = typeParameters.getProperty( DynamicParameterizedType.PROPERTY );
Annotation[] annotations;
if ( accessType == AccessType.FIELD ) {
annotations = ( (Field) new DirectPropertyAccessor().getGetter( classEntity, propertyName ).getMember() )
.getAnnotations();
}
else {
annotations = ReflectHelper.getGetter( classEntity, propertyName ).getMethod().getAnnotations();
}
final XProperty xProperty = (XProperty) typeParameters.get( DynamicParameterizedType.XPROPERTY );
// todo : not sure this works for handling @MapKeyEnumerated
final Annotation[] annotations = xProperty.getAnnotations();
typeParameters.put(
DynamicParameterizedType.PARAMETER_TYPE,
new ParameterTypeImpl( ReflectHelper.classForName( typeParameters
.getProperty( DynamicParameterizedType.RETURNED_CLASS ) ), annotations, table.getCatalog(),
table.getSchema(), table.getName(), Boolean.valueOf( typeParameters
.getProperty( DynamicParameterizedType.IS_PRIMARY_KEY ) ), columnsNames ) );
new ParameterTypeImpl(
ReflectHelper.classForName(
typeParameters.getProperty( DynamicParameterizedType.RETURNED_CLASS )
),
annotations,
table.getCatalog(),
table.getSchema(),
table.getName(),
Boolean.valueOf( typeParameters.getProperty( DynamicParameterizedType.IS_PRIMARY_KEY ) ),
columnsNames )
);
}
catch ( ClassNotFoundException cnfe ) {
throw new MappingException( "Could not create DynamicParameterizedType for type: " + typeName, cnfe );

View File

@ -474,6 +474,10 @@ public class EnumType implements EnhancedUserType, DynamicParameterizedType, Ser
}
}
public boolean isOrdinal() {
return isOrdinal( sqlType );
}
private boolean isOrdinal(int paramType) {
switch ( paramType ) {
case Types.INTEGER:

View File

@ -45,6 +45,7 @@ public interface DynamicParameterizedType extends ParameterizedType {
public static final String ENTITY = "org.hibernate.type.ParameterType.entityClass";
public static final String PROPERTY = "org.hibernate.type.ParameterType.propertyName";
public static final String ACCESS_TYPE = "org.hibernate.type.ParameterType.accessType";
public static final String XPROPERTY = "org.hibernate.type.ParameterType.xproperty";
public static interface ParameterType {

View File

@ -0,0 +1,63 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. 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 Inc.
*
* 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.test.annotations.enumerated.mapkey;
import org.hibernate.Session;
import org.junit.Test;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
/**
* @author Steve Ebersole
*/
public class MapKeyEnumeratedTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { User.class, SocialNetworkProfile.class };
}
@Test
public void testMapKeyEnumerated() {
Session s = openSession();
s.beginTransaction();
User user = new User(SocialNetwork.STUB_NETWORK_NAME, "facebookId");
s.save( user );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
user = (User) s.get( User.class, user.getId() );
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
user = (User) s.get( User.class, user.getId() );
s.delete( user );
s.getTransaction().commit();
s.close();
}
}

View File

@ -0,0 +1,32 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. 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 Inc.
*
* 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.test.annotations.enumerated.mapkey;
/**
* @author Dmitry Spikhalskiy
* @author Steve Ebersole
*/
public enum SocialNetwork {
STUB_NETWORK_NAME
}

View File

@ -0,0 +1,68 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. 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 Inc.
*
* 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.test.annotations.enumerated.mapkey;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
/**
* @author Dmitry Spikhalskiy
* @author Steve Ebersole
*/
@Entity
@Table(name = "social_network_profile", uniqueConstraints = {@UniqueConstraint(columnNames = {"social_network", "network_id"})})
public class SocialNetworkProfile {
@javax.persistence.Id
@javax.persistence.GeneratedValue(generator = "system-uuid")
@org.hibernate.annotations.GenericGenerator(name = "system-uuid", strategy = "uuid2")
@javax.persistence.Column(name = "id", unique = true)
private java.lang.String id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Enumerated(value = EnumType.STRING) //if change type to ordinal - test will not failure
@Column(name = "social_network", nullable = false)
private SocialNetwork socialNetworkType;
@Column(name = "network_id", nullable = false)
private String networkId;
protected SocialNetworkProfile() {
}
protected SocialNetworkProfile(User user, SocialNetwork socialNetworkType, String networkId) {
this.user = user;
this.socialNetworkType = socialNetworkType;
this.networkId = networkId;
}
}

View File

@ -0,0 +1,68 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. 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 Inc.
*
* 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.test.annotations.enumerated.mapkey;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.FetchType;
import javax.persistence.MapKeyColumn;
import javax.persistence.MapKeyEnumerated;
import javax.persistence.OneToMany;
import java.util.EnumMap;
import java.util.Map;
/**
* @author Dmitry Spikhalskiy
* @author Steve Ebersole
*/
@Entity
public class User {
@javax.persistence.Id
@javax.persistence.GeneratedValue(generator = "system-uuid")
@org.hibernate.annotations.GenericGenerator(name = "system-uuid", strategy = "uuid2")
@javax.persistence.Column(name = "id", unique = true)
private java.lang.String id;
@MapKeyEnumerated( EnumType.STRING )
@MapKeyColumn(name = "social_network")
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private Map<SocialNetwork, SocialNetworkProfile> socialNetworkProfiles = new EnumMap<SocialNetwork, SocialNetworkProfile>(SocialNetwork.class);
protected User() {
}
public User(SocialNetwork sn, String socialNetworkId) {
SocialNetworkProfile profile = new SocialNetworkProfile(this, sn, socialNetworkId);
socialNetworkProfiles.put(sn, profile);
}
public SocialNetworkProfile getSocialNetworkProfile(SocialNetwork socialNetwork) {
return socialNetworkProfiles.get(socialNetwork);
}
public String getId() {
return id;
}
}

View File

@ -0,0 +1,33 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. 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 Inc.
*
* 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.test.annotations.enumerated.ormXml;
/**
* @author Oliverio
* @author Steve Ebersole
*/
public enum Binding {
PAPERBACK,
HARDCOVER
}

View File

@ -0,0 +1,54 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. 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 Inc.
*
* 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.test.annotations.enumerated.ormXml;
/**
* @author Oliverio
* @author Steve Ebersole
*/
public class BookWithOrmEnum {
private Long id;
private Binding bindingOrdinalEnum;
private Binding bindingStringEnum;
public Long getId() {
return id;
}
public Binding getBindingOrdinalEnum() {
return bindingOrdinalEnum;
}
public void setBindingOrdinalEnum(Binding bindingOrdinalEnum) {
this.bindingOrdinalEnum = bindingOrdinalEnum;
}
public Binding getBindingStringEnum() {
return bindingStringEnum;
}
public void setBindingStringEnum(Binding bindingStringEnum) {
this.bindingStringEnum = bindingStringEnum;
}
}

View File

@ -0,0 +1,57 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2012, Red Hat Inc. 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 Inc.
*
* 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.test.annotations.enumerated.ormXml;
import org.hibernate.type.CustomType;
import org.hibernate.type.EnumType;
import org.hibernate.type.Type;
import org.junit.Test;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.junit4.ExtraAssertions;
import static org.junit.Assert.assertFalse;
/**
* @author Steve Ebersole
*/
@TestForIssue( jiraKey = "HHH-7645" )
public class OrmXmlEnumTypeTest extends BaseCoreFunctionalTestCase {
@Override
protected String[] getXmlFiles() {
return new String[] { "org/hibernate/test/annotations/enumerated/ormXml/orm.xml" };
}
@Test
public void testOrmXmlDefinedEnumType() {
Type bindingPropertyType = configuration().getClassMapping( BookWithOrmEnum.class.getName() )
.getProperty( "bindingStringEnum" )
.getType();
CustomType customType = ExtraAssertions.assertTyping( CustomType.class, bindingPropertyType );
EnumType enumType = ExtraAssertions.assertTyping( EnumType.class, customType.getUserType() );
assertFalse( enumType.isOrdinal() );
}
}

View File

@ -0,0 +1,15 @@
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd" version="2.0">
<entity name="bookWithOrmEnum" class="org.hibernate.test.annotations.enumerated.ormXml.BookWithOrmEnum" access="FIELD" metadata-complete="true">
<attributes>
<id name="id" />
<basic name="bindingOrdinalEnum">
<enumerated>ORDINAL</enumerated>
</basic>
<basic name="bindingStringEnum">
<column column-definition="VARCHAR(10)" />
<enumerated>STRING</enumerated>
</basic>
</attributes>
</entity>
</entity-mappings>