-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Using Enums does not work
PostPosted: Thu Jun 02, 2011 8:04 pm 
Beginner
Beginner

Joined: Sat May 21, 2011 7:40 am
Posts: 22
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?


Top
 Profile  
 
 Post subject: Re: Using Enums does not work
PostPosted: Mon Aug 01, 2011 12:37 pm 
Newbie

Joined: Mon Aug 01, 2011 12:34 pm
Posts: 1
Christian,

Just ran into same issue. All tests pass, but when app starts I get an error re: enum. Did you solve you problem? What was wrong in your instance?

thanks in advance.


Top
 Profile  
 
 Post subject: Re: Using Enums does not work
PostPosted: Wed Aug 03, 2011 6:09 am 
Senior
Senior

Joined: Tue Aug 04, 2009 7:45 am
Posts: 124
Christian, seems you try to use hibernate tools with hibernate 4, and I was not able to compile your user type. Instead I used user type from here(EnumUserType):
http://community.jboss.org/wiki/UserTyp ... CHARColumn

Code:
package xx;
public class PermissionUserType extends EnumUserType<PermissionEnum> {
    public PermissionUserType() {
        super(PermissionEnum.class);
    }
}


Code:
package xx;
public enum PermissionEnum {One, Two}


Code:
<hibernate-mapping>
   <typedef name="permission" class="xx.PermissionUserType"/>
    <class name="xx.Permission" table="Permission">
        <id name="id" type="int" access="field">
            <column name="id" />
            <generator class="assigned"></generator>
        </id>
        <property name="permission" access="field">
            <column name="permission" />
            <type name="permission"></type>
        </property>
    </class>
</hibernate-mapping>


The generated class is correct:
Quote:
public class Permission implements java.io.Serializable {
...
private PermissionEnum permission;


BTW. Hibernate 4 is not supported now with hibernate tools.


Top
 Profile  
 
 Post subject: Re: Using Enums does not work
PostPosted: Fri Sep 02, 2011 12:27 am 
Newbie

Joined: Fri Sep 02, 2011 12:27 am
Posts: 1
hi everyone ..

_________________
bulging disk treatments - minimally invasive spine surgery - back surgery


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.