Hi, Emmanuel,
Thanks so much for you work on Hibernate annotations. It's making maintaining our mappings *so* much easier.
One of the features of HibAnn I haven't been able to get working yet is the automatic support for Java 1.5 Enums. I'm using Oracle 10g, Hibernate 3.1 beta1, and Hibernate Annotations 3.1 beta4. EnumType is currently failing to determine the correct backing sql type for our enum properties and is defaulting to treat it as an integer. Unfortunately, nearly all of our enums are represented by their string names. It's not a hugely pressing issue; I've got workarounds with my own EnumUserType class and the appropriate type declarations. However, getting this feature working would be awesome.
So, the problem I'm facing is in getting the correct "schema" into EnumType. In EnumType.guessType, there's the following call to retrieve the column meta data:
Code:
rs = statement.getConnection().getMetaData().getColumns(catalog, schema, table, column);
In our setup, 'schema' is null; we don't specify it on any of our tables. Unfortunately, a null schema used with getColumns returns information for every 'user' in our Oracle db. We tend to have multiple copies of our schema in Oracle, each associated with a different username, and the schema for these instances is the same as the associated username. So, even though each of these table/column combos have the same type, the current implementation of 'guessType' will because there's more than one row in the resultset. If I hardcode a schema into the Table annotation, the lookup works. Unfortnately, hardcoding a schema into the annotations isn't an option, because we have multiple oracle installations (dev, test, production) each with their own usernames/schemas.
I've tried several approaches to getting the schema into EnumType programmatically, but none of them worked:
- Neither EnumType nor AnnotationBinder (which configures the EnumType) honors the hibernate.default_schema setting.
- I created a custom annotation and Hibernate Validator that implemented both PropertyConstraint and PersistentClassConstraint. The apply method for both intf's was implemented to get the table and set its schema. I added this annotation at both the property and class level, and while my apply methods were called, they were called *after* the enum property itself had been initialized, so it didn't see the updated schema.
- As a last-ditch effort, I tried to set @Column.columnDefinition property to be a VARCHAR, but EnumType didn't honor this setting, either.
At this point, I'm stymied. I don't know if there's some configuration of either Hibernate or Oracle that will produce the results I want, or if this is an actual bug in Hibernate annotations. If this is a shortcoming of EnumType, I can think of some possible changes that would help this problem:
- If there are multiple rows returned from the above call, don't fail immediately. EnumType could check if all the returned rows have the same DATA_TYPE, and if so, use that. If this is an acceptable solution, I would enter a JIRA issue and submit a patch.
- Honor hibernate.default_schema setting if no schema is otherwise specified. I'm not sure how to implement this, if this would be in AnnotationBinder or EnumType, and how it would get access to this setting. But it seems like a reasonable thing to do, regardless.
- Try to discern the backing type from @Column.columnDefinition, if specified. Not sure if this is an acceptable solution, or if this is an appropriate use of this annotation. Just an idea.
- Process validators before normal annotations. Again, this might not be a reasonable change, nor would I know how to go about making this change even if it were. But the current ordering makes it impossible to change a schema through a validator in time for EnumType to recognize it. Perhaps this is just the way it has to be...
I'm also open to other suggestions. I've tried to do as much investigation as possible before creating this post, but I almost certainly may have missed something.
Thanks for any suggestions you may have. Let me know if you need any further information.