hello!
my problem is that i want to use an enum as field type like this:
Code:
...
<typedef name="permission" class="com.blazebit.web.cms.model.enums.GenericEnumUserType">
<param name="enumClass">com.blazebit.web.cms.model.enums.PermissionEnum</param>
</typedef>
<class...
<property name="permission" type="permission">
<column name="perm_permission">
<comment>The permission as enum value.</comment>
</column>
</property>
...
I am using the following implementation for the user type:
Code:
package com.blazebit.web.cms.model.enums;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.hibernate.HibernateException;
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
import org.hibernate.type.AbstractStandardBasicType;
import org.hibernate.type.TypeResolver;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;
/**
* Look here for more info on design.
* http://community.jboss.org/wiki/Java5EnumUserType
* modify to use AbstractStandardBasicType instead.
* @author Chun ping Wang.
*
*/
public class GenericEnumUserType implements UserType, ParameterizedType {
private static final long serialVersionUID = -1854479466843620961L;
private static final String DEFAULT_IDENTIFIER_METHOD_NAME = "name";
private static final String DEFAULT_VALUE_OF_METHOD_NAME = "valueOf";
private Class<? extends Enum> enumClass;
private Class<?> identifierType;
private Method identifierMethod;
private Method valueOfMethod;
private AbstractStandardBasicType<? extends Object> type;
private int[] sqlTypes;
public GenericEnumUserType(){
}
@Override
public void setParameterValues(Properties parameters) {
String enumClassName = parameters.getProperty("enumClass");
try {
enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
} catch (ClassNotFoundException cfne) {
throw new HibernateException("Enum class not found", cfne);
}
String identifierMethodName = parameters.getProperty("identifierMethod", DEFAULT_IDENTIFIER_METHOD_NAME);
try {
identifierMethod = enumClass.getMethod(identifierMethodName, new Class[0]);
identifierType = identifierMethod.getReturnType();
} catch (Exception e) {
throw new HibernateException("Failed to obtain identifier method", e);
}
type = (AbstractSingleColumnStandardBasicType<? extends Object>) new TypeResolver().heuristicType(identifierType.getName(), parameters);
if (type == null) {
throw new HibernateException("Unsupported identifier type " + identifierType.getName());
}
sqlTypes = new int[]{((AbstractSingleColumnStandardBasicType<?>) type).sqlType()};
String valueOfMethodName = parameters.getProperty("valueOfMethod", DEFAULT_VALUE_OF_METHOD_NAME);
try {
valueOfMethod = enumClass.getMethod(valueOfMethodName, new Class[]{identifierType});
} catch (Exception e) {
throw new HibernateException("Failed to obtain valueOf method", e);
}
}
@Override
public Class<? extends Enum> returnedClass() {
return enumClass;
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
Object identifier = type.get(rs, names[0], null);
if (rs.wasNull()) {
return null;
}
try {
return valueOfMethod.invoke(enumClass, new Object[]{identifier});
} catch (Exception e) {
throw new HibernateException("Exception while invoking valueOf method '" + valueOfMethod.getName() + "' of "
+ "enumeration class '" + enumClass + "'", e);
}
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
try {
if (value == null) {
st.setNull(index, ((AbstractSingleColumnStandardBasicType<?>) type).sqlType());
} else {
Object identifier = identifierMethod.invoke(value, new Object[0]);
type.nullSafeSet(st, identifier, index, null);
}
} catch (Exception e) {
throw new HibernateException("Exception while invoking identifierMethod '" + identifierMethod.getName() + "' of "
+ "enumeration class '" + enumClass + "'", e);
}
}
@Override
public int[] sqlTypes() {
return sqlTypes;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x == y;
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
hbm2java does something strange it generates the class like this:
Code:
...
class Permission implements java.io.Serializable{
private GenericEnumUserType permission;
....
}
Shouldn't it generate the field with the type PermissionEnum?
The next thing is that i get the following error when i try to start my application:
Code:
Method public java.lang.String org.hibernate.tool.hbm2x.pojo.BasicPOJOClass.getJavaTypeName(org.hibernate.mapping.Property,boolean) threw an exception when invoked on Entity: com.blazebit.web.cms.model.Permission
The problematic instruction:
----------
==> ${pojo.getJavaTypeName(field, jdk5)} [on line 6, column 45 in pojo/PojoFields.ftl]
in include "PojoFields.ftl" [on line 8, column 1 in pojo/Pojo.ftl]
----------
Java backtrace for programmers:
----------
freemarker.template.TemplateModelException: Method public java.lang.String org.hibernate.tool.hbm2x.pojo.BasicPOJOClass.getJavaTypeName(org.hibernate.mapping.Property,boolean) threw an exception when invoked on Entity: com.blazebit.web.cms.model.Permission
at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:136)
at freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:93)
at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
at freemarker.core.Expression.getStringValue(Expression.java:93)
at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:79)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:160)
at freemarker.core.Environment.visit(Environment.java:351)
at freemarker.core.IteratorBlock.accept(IteratorBlock.java:95)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.Environment.include(Environment.java:1375)
at freemarker.core.Include.accept(Include.java:155)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.IfBlock.accept(IfBlock.java:82)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.Environment.visit(Environment.java:233)
at freemarker.core.BlockAssignment.accept(BlockAssignment.java:83)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:196)
at freemarker.core.Environment.process(Environment.java:176)
at freemarker.template.Template.process(Template.java:232)
at org.hibernate.tool.hbm2x.TemplateHelper.processTemplate(TemplateHelper.java:255)
at org.hibernate.tool.hbm2x.TemplateProducer.produceToString(TemplateProducer.java:67)
at org.hibernate.tool.hbm2x.TemplateProducer.produce(TemplateProducer.java:28)
at org.hibernate.tool.hbm2x.TemplateProducer.produce(TemplateProducer.java:103)
at org.hibernate.tool.hbm2x.GenericExporter.exportPOJO(GenericExporter.java:148)
at org.hibernate.tool.hbm2x.GenericExporter.exportPersistentClass(GenericExporter.java:137)
at org.hibernate.tool.hbm2x.GenericExporter$2.process(GenericExporter.java:43)
at org.hibernate.tool.hbm2x.GenericExporter.doStart(GenericExporter.java:128)
at org.hibernate.tool.hbm2x.AbstractExporter.start(AbstractExporter.java:95)
at org.codehaus.mojo.hibernate3.HibernateExporterMojo.doExecute(HibernateExporterMojo.java:273)
at org.codehaus.mojo.hibernate3.HibernateExporterMojo.execute(HibernateExporterMojo.java:152)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at freemarker.ext.beans.BeansWrapper.invokeMethod(BeansWrapper.java:616)
at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:113)
... 63 more
Caused by: java.lang.VerifyError: (class: org/hibernate/type/BasicTypeRegistry, method: <init> signature: ()V) Incompatible argument to function
at org.hibernate.type.TypeResolver.<init>(TypeResolver.java:59)
at com.blazebit.web.cms.model.enums.GenericEnumUserType.setParameterValues(GenericEnumUserType.java:61)
at org.hibernate.type.TypeFactory.injectParameters(TypeFactory.java:362)
at org.hibernate.type.CustomType.<init>(CustomType.java:90)
at org.hibernate.type.TypeFactory.heuristicType(TypeFactory.java:268)
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:283)
at org.hibernate.tool.hbm2x.visitor.JavaTypeFromValueVisitor.handle(JavaTypeFromValueVisitor.java:83)
at org.hibernate.tool.hbm2x.visitor.DefaultValueVisitor.accept(DefaultValueVisitor.java:94)
at org.hibernate.mapping.SimpleValue.accept(SimpleValue.java:323)
at org.hibernate.tool.hbm2x.Cfg2JavaTool.getJavaTypeName(Cfg2JavaTool.java:298)
at org.hibernate.tool.hbm2x.Cfg2JavaTool.getRawTypeName(Cfg2JavaTool.java:265)
at org.hibernate.tool.hbm2x.Cfg2JavaTool.getJavaTypeName(Cfg2JavaTool.java:180)
at org.hibernate.tool.hbm2x.pojo.BasicPOJOClass.getJavaTypeName(BasicPOJOClass.java:859)
... 69 more
But my tests are executing well. Within my test i create a Session object and it works without the error.
What is the problem?