reversing java to c enum style mapping

A

Aryeh M. Friedman

I have the following:

package isu.db;

/**
* Create a mapping between int enums and symbolic ones (i.e. C to
Java style)
*
* @author Aryeh M. Friedman
* @version 12/19/09
*/
public interface DBEnum
{
/**
* Get the C style value of the enum
*
* @return the int (C style) version of the enum
*/
public int getValue();
}

package isu.campus;

import isu.db.DBEnum;

/**
* The type of campus we are dealing with
*
* @author Aryeh M. Friedman
* @version 12/19/09
*/
public enum CampusType implements DBEnum
{
TwoYear(0),
Trade(1),
FourYear(2),
Univeristy(3),
Seminary(4),
Acaedemy(5),
MedSchool(6),
LawSchool(7),
GradOnly(8),
PostDoc(9);

CampusType(int value)
{
this.value=value;
}

public int getValue()
{
return value;
}

private int value;
}

When we store each enum in our DB we do it as the int xxx.value for
that enum... I am looking for a non O(n) method (i.e. no need to loop
through each value looking for a match) for turning the DB field into
an in RAM enum... ideas?
 
J

Joshua Cranmer

Aryeh said:
I have the following:
public interface DBEnum
{
/**
* Get the C style value of the enum
*
* @return the int (C style) version of the enum
*/
public int getValue();
}

You probably don't need this:
When we store each enum in our DB we do it as the int xxx.value for
that enum... I am looking for a non O(n) method (i.e. no need to loop
through each value looking for a match) for turning the DB field into
an in RAM enum... ideas?

If you use the ordinal, you can do:
CampusType.values()[ordinal].
 
M

Mark Space

Aryeh said:
When we store each enum in our DB we do it as the int xxx.value for
that enum... I am looking for a non O(n) method (i.e. no need to loop
through each value looking for a match) for turning the DB field into
an in RAM enum... ideas?

Two thoughts:

1. Don't use Java enums for this. It's a bad match for DB values, which
are really just ints. You should check the table schema each time you
start this program, reading the "enum" values from the DB, and store
them for later use. If you use Java enums instead, every time someone
edits the database schema you may have to change your program. Not fun,
and bad practice to boot.


2. For future reference, the O(1) look up method is:

enum Dir {EAST, WEST, SOUTH, NORTH }
Dir [] dirs = Dir.class.getEnumConstants();

which will give you an array of Enum values, in the order defined. You
can then do look-ups, based on an ordinal, in this array to find the
corresponding Enum.

dirs[0] == EAST, dirs[1] == WEST, etc.


<http://java.sun.com/javase/6/docs/api/java/lang/Class.html#getEnumConstants()>

But don't build your DB this way, just build the values at runtime.
 
R

Roedy Green

But don't build your DB this way, just build the values at runtime.

Another way to approach this is to look for Enum support in the
database. MySQL for example will expand database values to words for
enum-like support. If those words are the same names as Enum constants
you are done.
--
Roedy Green Canadian Mind Products
http://mindprod.com

One path leads to despair and utter hopelessness. The other,
to total extinction. Let us pray we have the wisdom to choose correctly.
~ Woody Allen .
 
M

Mark Space

Roedy said:
Another way to approach this is to look for Enum support in the
database. MySQL for example will expand database values to words for
enum-like support. If those words are the same names as Enum constants
you are done.


I hadn't noticed that option, thanks. Last time I checked I think the
enum words appeared as part of the table schema, and the actual values
you retrieved were just ints, unless you made a new table and did a
join, manually.
 
L

Lew

Mark said:
I hadn't noticed that option, thanks. Last time I checked I think the
enum words appeared as part of the table schema, and the actual values
you retrieved were just ints, unless you made a new table and did a
join, manually.

For Standard SQL, it is best to use CHAR or VARCHAR to represent the enum, or
follow Mark Space's original advice to build the Java representation at run
time. I don't know why anyone would represent an enum (or enum-like thing) as
in INTEGER in a database. To do so is fragile at best.

FWIW, Postgres has an ENUM type also.
 
A

Arne Vajhøj

Lew said:
For Standard SQL, it is best to use CHAR or VARCHAR to represent the
enum, or follow Mark Space's original advice to build the Java
representation at run time. I don't know why anyone would represent an
enum (or enum-like thing) as in INTEGER in a database. To do so is
fragile at best.

Most other (commonly used) languages do treat enums as ints, so ...

Arne
 
A

Arne Vajhøj

Lew said:
But we are discussing Java. So ...

Actually not. You were discussing database design.

Database design can very well be influenced by other languages
than.

Arne
 
L

Lew

Arne said:
Actually not. You were discussing database design.

Database design can very well be influenced by other languages
than.

Actually so. I was discussing database design in the context of Java
programming, hence the post in clj.programmer and not a database newsgroup.

I guess I gave the group too much credit for understanding that.
 
A

Arne Vajhøj

Lew said:
Actually so. I was discussing database design in the context of Java
programming, hence the post in clj.programmer and not a database newsgroup.

It may be your experience that databases get designed for use
with Java, but that is far from universal.

Arne
 
D

Daniel Pitts

Lew said:
For Standard SQL, it is best to use CHAR or VARCHAR to represent the
enum, or follow Mark Space's original advice to build the Java
representation at run time. I don't know why anyone would represent an
enum (or enum-like thing) as in INTEGER in a database. To do so is
fragile at best.

FWIW, Postgres has an ENUM type also.

In order to normalize the data, you might use an Integer, but that
integer would be a fk into a table that has the varchar name of the enum.

I personally like this approach, because it decouples the name from the
semantics, but allows the name to be available for use.
 
L

Lew

It may be your experience that databases get designed for use
with Java, but that is far from universal.

It is not my desire to claim that it is universal. It is my desire to talk
about how to design databases a) specifically for Java, and b) in a way that
reduces fragility. Even if the access language were C, I would still suggest
that one avoid using INTEGER as the database type for an enum.

I note that Postgres's ENUM type uses symbols similar to text, not numbers.
Apparently someone designing databases for general use agrees with me.
 
A

Arne Vajhøj

Daniel said:
In order to normalize the data, you might use an Integer, but that
integer would be a fk into a table that has the varchar name of the enum.

I am not sure that I would call it normalize, because i don't think it
is enforced by any 1NF-5NF rules.

But it is a way to enforce the valid range of values.

A way that is rather portable.

Some databases allow you to specify range of values, but that
is database specific.
I personally like this approach, because it decouples the name from the
semantics, but allows the name to be available for use.

It is widely used.

Arne
 
L

Lew

Daniel said:
In order to normalize the data, you might use an Integer, but that
integer would be a fk into a table that has the varchar name of the enum.

That's not normalization unless the number has a problem-domain interpretation.
I personally like this approach, because it decouples the name from the
semantics, but allows the name to be available for use.

What semantics are in a number?

One shouldn't try to match the integer in the database with the ordinal of the
Java enum. That is the part that is fragile. It couples the order of enum
constants in the middleware with the (presumably surrogate) integer key in the DB.

However, it still seems like too much even just in the database - why not just
store the string and skip the number? This is not a denorm if the string is
the PK of the database enum.
 
M

Mark Space

Daniel said:
In order to normalize the data, you might use an Integer, but that
integer would be a fk into a table that has the varchar name of the enum.

I personally like this approach, because it decouples the name from the
semantics, but allows the name to be available for use.

That would be my guess too: the enum-as-integer approach is just a
short-hand notation for using an int as a unique ID and a join to a
table with the values as strings.

My recollection for the enum approach though was that it only actually
yielded an integer. The DB didn't return a string, just an int. You
had to assume on the client side that you knew what string to use for
what int.

I don't pretend to be an expert on this subject however.
 
J

John B. Matthews

It may be your experience that databases get designed for use
with Java, but that is far from universal.

It is not my desire to claim that it is universal. It is my desire
to talk about how to design databases a) specifically for Java, and
b) in a way that reduces fragility. Even if the access language were
C, I would still suggest that one avoid using INTEGER as the database
type for an enum.

I note that Postgres's ENUM type uses symbols similar to text, not
numbers. Apparently someone designing databases for general use
agrees with me.[/QUOTE]

Somewhat tangentially, the serialization of an enum constant consists
solely of its name:

<http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html>
 
A

Arne Vajhøj

John said:
[QUOTE="Lew said:
Actually so. I was discussing database design in the context of
Java programming, hence the post in clj.programmer and not a
database newsgroup.
Arne said:
It may be your experience that databases get designed for use
with Java, but that is far from universal.
It is not my desire to claim that it is universal. It is my desire
to talk about how to design databases a) specifically for Java, and
b) in a way that reduces fragility. Even if the access language were
C, I would still suggest that one avoid using INTEGER as the database
type for an enum.

I note that Postgres's ENUM type uses symbols similar to text, not
numbers. Apparently someone designing databases for general use
agrees with me.

Somewhat tangentially, the serialization of an enum constant consists
solely of its name:

<http://java.sun.com/javase/6/docs/platform/serialization/spec/serial-arch.html>[/QUOTE]

Java picked an approach to enums that were significantly different
from C/C++/C#.

They did not want Java enums to be camouflaged ints.

Arne
 
A

Arne Vajhøj

Lew said:
What semantics are in a number?

One shouldn't try to match the integer in the database with the ordinal
of the Java enum. That is the part that is fragile. It couples the
order of enum constants in the middleware with the (presumably
surrogate) integer key in the DB.

However, it still seems like too much even just in the database - why
not just store the string and skip the number? This is not a denorm if
the string is the PK of the database enum.

Unless the database allow constraints on range, then the database
can not enforce the range.

A FK to another table can in most databases.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top