This discussion is archived
1 2 Previous Next 16 Replies Latest reply: Feb 20, 2013 8:59 PM by r035198x RSS

help with enumerations

REDO LOG Newbie
Currently Being Moderated
Hi all

I am about working on enumerations in a web project where I have an EncryptionLevel enumeration witch I need tu use an enumeration in a JPA entity :

package com.enumerations;

public enum EncryptionLevel {
     
     /*
      * 
      * 
      * encryption levels
      * 0: No Encryption
      * 1: Encryption Level 1
      * 2: Encryption Level 2
      * 3: Encryption Level 3
      */

}
if I use an ordinal enumeration, I will not be able to put descriptions because they contain tabulations

and if I use a string enumeration I will not be able to put 0,1,2 and 3 as identifiers

so how can I put descriptions (No Encryption, Encryption Level 1, ....) to the numbers 0, 1,2 and 3 that will be persisted in the database?

thanks for help

best regards rachid
  • 1. Re: help with enumerations
    TPD-Opitz-Consulting-com Expert
    Currently Being Moderated
    REDO LOG wrote:
    if I use an ordinal enumeration, I will not be able to put descriptions because they contain tabulations

    and if I use a string enumeration I will not be able to put 0,1,2 and 3 as identifiers

    so how can I put descriptions (No Encryption, Encryption Level 1, ....) to the numbers 0, 1,2 and 3 that will be persisted in the database?
    enums are almost like any other Java cass accept that there is a fixed set of object instantiated. So you can declare any method you may need, including Constructors:
    public enum EncryptionLevel {
       No_Encryption("No Encryption","description for\n\t 'No Encryption'"),
       Encryption_Level_1("Encryption Level 1","description for\n\t 'Encryption Level 1'"),
       // other enum constants
     ;
      private String databaseValue,description;
      EncryptionLevel (String databaseValue,String description){
         this.databaseValue=databaseValue;
         this.description=description;
      }
      public getDatabaseValue() { return databaseValue;}
      public getDescription() { return description;}
    }
    bye
    TPD
  • 2. Re: help with enumerations
    REDO LOG Newbie
    Currently Being Moderated
    Hi,
    thanks for replying, good idea
    here is my context: I have this portion of code in a jsf page where I want to select the category of encryption to submit the form to the database:

     
          <h:outputLabel value="Category"/>
          <p:selectOneMenu value="#{employeeBean.newEmployee.category}">
             <f:selectItems value="#{employeeBean.categories}" var="category"
                            itemLabel="#{category.description}"
                            itemValue="#{category.databaseValue}"/>
          </p:selectOneMenu>
    the problem is that it gives the following error: *'0' must be converted to an enum*

    I faced that problem with another enumeration but get it sorted like this:

    <h:outputLabel value="Gender"/>
          <p:selectOneMenu value="#{employeeBean.newEmployee.gender}">
             <f:selectItems value="#{employeeBean.genders}" var="gender"
                            itemLabel="#{gender.description}"
                            itemValue="#{gender}"/>
          </p:selectOneMenu>
    where the enumeration gender is as :

    public enum Gender {
         M("Male"), F("Female");
         
         private String description;
         
    
         public String getDescription() {
              return description;
         }
         
         
         public void setDescription(String description) {
              this.description = description;
         }
    
         private Gender(String description) {
              this.description = description;
         }
         
         
    
    }
  • 3. Re: help with enumerations
    r035198x Pro
    Currently Being Moderated
    Why do you need to store the values 0,1,2 in the database? JPA will use use the name() of the enum for persistence so they have to be valid enum identifiers. Do the same thing you did with the genders and only access the, 0,1, values within your application by calling a method on the enum. The persistence provider doesn't need to know about all the other methods or properties that the enum has. Those details are all in your code.
  • 4. Re: help with enumerations
    REDO LOG Newbie
    Currently Being Moderated
    I need to have the 0,1,2.. values in the database because that is specified to have it the database, now I can't put numbers in the enum, I have to put an identifier
    please explain more if It seems that I couldn't understand
    thanks for help
  • 5. Re: help with enumerations
    r035198x Pro
    Currently Being Moderated
    REDO LOG wrote:
    I need to have the 0,1,2.. values in the database because that is specified to have it the database, now I can't put numbers in the enum, I have to put an identifier
    please explain more if It seems that I couldn't understand
    thanks for help
    You could still try it with EnumType ordinal but it's dangerous with data because some seemingly innocent refactoring will mess up the data. I would just use a Entity with the other static properties defined as @Transient
  • 6. Re: help with enumerations
    aksarben Journeyer
    Currently Being Moderated
    Yes, you can accomplish what you describe with enum's. We do it all the time.

    For example, you can have one member variable (passed into the constructor) which is the database code, another which is a string displayed in drop down menus, & any other values you need. You're limited only by your imagination.
  • 7. Re: help with enumerations
    REDO LOG Newbie
    Currently Being Moderated
    that is what I want to be sure about: is the problem in my understanding of the situation?

    I heard about all what you have said, my problem is enough clear( I think, otherwise I re-explain)
    the drop down list should give: No Encryption, Encryption Level 1, Encryption Level 2, Encryption Level 3,
    the database values will be respectively: 0,1,2 and 3, so My enumeration will be an string enumerated type, because the the ordinal one couldn't have identifiers with space.

    the enumeration:
    public enum EncryptionLevel {
         
         No_Encryption("No Encryption", "0"), 
         Encryption_Level_1("Encryption Level 1","1"),
         Encryption_Level_2("Encryption Level 2","2"),
         Encryption_Level_3("Encryption Level 3","3");
    
         private String description;
         private String databaseValue;
    
         public String getDescription() {
              return description;
         }
         
         public String getDatabaseValue() {
              return databaseValue;
         }
    
         private EncryptionLevel(String description, String databaseValue){
              this.description = description;
              this.databaseValue = databaseValue;
         }
    
    }
    now in the managed bean I have an array on the encryption levels : levels  = EnryptionLevel.values()
    and in the add page I have the drop down list as follows:
      <h:outputLabel value="Level"/>
          <p:selectOneMenu value="#{employeeBean.service.encryptionLevel}">
             <f:selectItems value="#{employeeBean.levels}" var="level"
                            itemLabel="#{level.description}"
                            itemValue="#{level.databaseValue}"/>
          </p:selectOneMenu>
    this generates the *'0' must be converted to an enum*

    so sorry if I bothered you
    and thanks for your help

    Edited by: REDO LOG on Feb 20, 2013 2:22 PM
  • 8. Re: help with enumerations
    TPD-Opitz-Consulting-com Expert
    Currently Being Moderated
    try oberriding <tt>valueOf()</tt> in the enum:
    public enum EncryptionLevel {
         
         No_Encryption("No Encryption", "0"), 
         Encryption_Level_1("Encryption Level 1","1"),
         Encryption_Level_2("Encryption Level 2","2"),
         Encryption_Level_3("Encryption Level 3","3");
     // ...
       public EncryptionLevel valueOf(String value){
          try{ 
            return values()[Integer.parseInt(value)];
          } catch (IndexOutOfBoundsException|NumberFormatException ex){
             throw new RuntimeException("could not convert "+value+" to an encryption type!",ex);
         }
      }
    bye
    TPD
  • 9. Re: help with enumerations
    REDO LOG Newbie
    Currently Being Moderated
    hi thanks for help, but I get this error when overriding the method : The enum Category already defines the method valueOf(String) implicitly
  • 10. Re: help with enumerations
    TPD-Opitz-Consulting-com Expert
    Currently Being Moderated
    REDO LOG wrote:
    already defines the method valueOf(String) implicitly*
    Java prevents you from accidently overriding a method, so you must tell it that this ovrride is intended. (<tt>@Override</tt>)

    bye
    TPD
  • 11. Re: help with enumerations
    REDO LOG Newbie
    Currently Being Moderated
    that was exactly what I did :) but the same error
  • 12. Re: help with enumerations
    TPD-Opitz-Consulting-com Expert
    Currently Being Moderated
    Looks like we cannot override <tt>valueOf()</tt> :o(

    Then we have to do it the other way around. Change your jsp to return the enums identifiers:
    <f:selectItems value="#{employeeBean.levels}" var="level"
                            itemLabel="#{level.description}"
                            itemValue="#{level.toString}"/><!-- dunno if '.toString' could be ommitted-->
    bye
    TPD
  • 13. Re: help with enumerations
    gimbal2 Guru
    Currently Being Moderated
    Yes it can be omitted. What you're doing seems illegal anyway, you're accessing a method as a property. I'm not 100% sure, but i believe to do a method invocation in an EL expression you need to add the parenthesis.
    itemValue="#{level.toString()}"
  • 14. Re: help with enumerations
    REDO LOG Newbie
    Currently Being Moderated
    Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
    Internal Exception: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'encryption_level' at row 1
    anyhow, thanks to all of you, you have made good efforts I appreciate that
    thanks ones again
1 2 Previous Next

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points