Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using enum as id

Tags:

java

jpa

openjpa

Using JPA, can we define an enum as id of an entity?

I've tried the following:

public enum AssetType {
   ....
}

@Entity
@IdClass(AssetType.class)
public class Adkeys {

   private AssetType type;

   @Id
   @Enumerated(EnumType.STRING)
   @Column(nullable = false)
   public AssetType getType() {
      return type;
   }

}

Using OpenJPA, it complains:

org.apache.openjpa.persistence.ArgumentException: The id class "class aa.AssetType" specified by type "class aa.Adkeys" does not have a public no-args constructor.

So my questions are:

  • should we able to use enum as id for an entity on JPA? (i.e. there is a bug in OpenJPA)
  • or do I make a mistake somewhere?
  • and is there any workaround for such problem?
like image 545
nanda Avatar asked Sep 15 '10 12:09

nanda


People also ask

Can enum be used as a key in map?

EnumMap is a specialized map implementation that uses only Enum type key. In HashMap, we can use Enum as well as any other object as a key.

Can enum names be numbers?

Enum instances must obey the same java language naming restrictions as other identifiers - they can't start with a number. If you absolutely must have hex in the name, prefix them all with a letter/word, for example the enum class itself: public enum Tag { Tag5F25, Tag4F, ... }

How do you declare an enum variable?

An enum is defined using the enum keyword, directly inside a namespace, class, or structure. All the constant names can be declared inside the curly brackets and separated by a comma. The following defines an enum for the weekdays. Above, the WeekDays enum declares members in each line separated by a comma.

How do you find the value of an enum?

Get the value of an Enum To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.


1 Answers

The JPA spec doesn't say this is possible:

2.1.4 Primary Keys and Entity Identity

The primary key (or field or property of a composite primary key) should be one of the following types: any Java primitive type; any primitive wrapper type; java.lang.String; java.util.Date; java.sql.Date. In general, however, approximate numeric types (e.g., floating point types) should never be used in primary keys. Entities whose primary keys use types other than these will not be portable.

If you really want to have a compile-time fixed number of records for a given entity, you can use a String or int primary key and assign it AssetType.FOO.name() or AssetType.FOO.ordinal()

And non-portable here means that some persistence provider may support other things, but it might not work for another provider. As with the enum - if the persistence provider has special support for it, that does not try to instantiate it, but rather processes it specially after checking if class.isEnum(), then it might work. But it seems your persistence provider doesn't do this.

like image 57
Bozho Avatar answered Nov 15 '22 17:11

Bozho