Using enum as id

nanda picture nanda · Sep 15, 2010 · Viewed 8.1k times · Source

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?

Answer

Bozho picture Bozho · Sep 15, 2010

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.