Using enums in java

Asked

Viewed 561 times

1

I created an Enum and I need to set the values in the bank that way:

  • If it is Revenue, the value is 0;
  • If it is Expense, the value is 1;

This is my Enum:

 public enum EntryType {
   INCOME, OUTPUT;
 }

In my java controller, the type comes as String, because I’m getting the value of a radio button:

  <input type="radio" name="income" id="radio-income" value="INCOME"
  ng-model="entry.type">
  <label for="radio-income"><span></span>Entrada</label>

  <input type="radio" name="output" id="radio-output" value="OUTPUT" 
  ng-model="entry.type">
  <label for="radio-output"><span></span>Saída</label>

That’s the definition of Entrytype in my entity:

@Enumerated(EnumType.STRING)  // Ja tentei com EnumType.Ordinal
@Column(name = "type")
private EntryType type;

How do I take the Enum ordinal value to set in the database, instead of setting the string?

  • There is no error, I only need to set 0 or 1 and currently Seto as INCOME or OUTPUT.

1 answer

1


I don’t recommend using the ordinal enum as her identifier in the database. If you do this, adding a new element in the enumeration that is not at the end or reordering them will generate an inconsistency in your database since the ordinal will change. Example:

Suppose you have the following enumeration:

public enum User Role {
    
    REGISTERED_USER, ADMIN;
}

In this case, in your database you would have users with the privilege REGISTERED_USER with the value 0 and ADMIN value 1. Now suppose you add a new UserRole:

public enum UserRole {
    
    REGISTERED_USER, GUEST, ADMIN;
}

From now on, REGISTERED_USER has a value of 0, GUEST has a value of 1 and ADMIN the value 2. That is, all ADMIN became GUEST!

Solution:

What you can do is assign a id to each element and implement a AttributeConverter. That way, for every new element you add, just assign a new identifier that doesn’t need to be sequential.

Entrytype.java

public enum EntryType {
    INCOME(0), 
    
    OUTPUT(1);
    
    //para uso interno
    //evita que arrays sejam criados desnecessariamente
    private static final EntryType VALUES[] = EntryType.values();
    
    private final int identificador;
    
    private EntryType(int identificador) {
        this.identificador = identificador;
    }
    
    public final int getIdentificador() {
        return identificador;
    }
    
    //Caso queira, pode retornar um optional ao invés de lançar um exceção
    public static final EntryType deIdentificador(int identificador) {
        for(EntryType et : VALUES) {
            if(et.identificador == identificador) {
                return et;
            }
        }
        throw new IllegalArgumentException("identificador inválido: " + identificador);
    }
}

Entrytypeconverter

public final class EntryTypeConverter implements AttributeConverter<EntryType, Integer> {

    @Override
    public final Integer convertToDatabaseColumn(EntryType attribute) {
        return attribute.getIdentificador();
    }

    @Override
    public final EntryType convertToEntityAttribute(Integer dbData) {
        return EntryType.deIdentificador(dbData);
    }

}

In its entity:

@Column(name = "type")
@Convert(converter=EntryTypeConverter.class)
private EntryType type;
  • Felipe, thank you so much for your help, it worked! But I have another question: How do I not have to set this in my HTML input? <input type="radio" value="OUTPUT" ng-model="entry.type"> . There’s some way to do it differently?

  • @Guilhermenass This depends on the technologies you are using to generate the HTML page and to receive the object on the server side. Maybe it’s better to create another question since it’s a different topic.

  • All right, thank you Felipe, you helped me a lot, man, I got my problem solved with your help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.