This is basically a follow-up question or repost as question How to use enums with JPA seems to have been solved in a proprietary way. This is the 2012 JPA question of basically the same, here using EclipseLink 2.3.2.
The question is how to map a Java enum to a DB string with different names. There is a DB column with the VARCHAR values 'M'
, 'C'
, 'N'
, and 'F'
. They are cryptic and mix English and German. To improve the business layer I want to map a Java enum to the above DB strings:
public enum TradingSector
{
EMPLOYEE( "M" ), // Mitarbeiter
CUSTOMER( "C" ),
NOSTRO( "N" ),
FUND( "F" );
// this works:
// M( "M" ),
// C( "C" ),
// N( "N" ),
// F( "F" );
private final String ch;
private TradingSector( String ch )
{
this.ch = ch;
}
@Override
public String toString()
{
return this.ch;
}
}
Here's the entity:
@Entity
@Table( name = "TRADES" )
@Inheritance( strategy = InheritanceType.SINGLE_TABLE )
@DiscriminatorColumn( name = "NOSTRO_FLAG", discriminatorType = DiscriminatorType.STRING, length = 1 )
public class Trade implements Serializable
{
@Enumerated( EnumType.STRING )
@Column( name = "NOSTRO_FLAG", insertable = false, updatable = false )
private TradingSector discriminator;
...
}
This is kind of special, mapping an enum to what is already the inheritance discriminator. This however should work, as the enums named like the DB strings show.
The TRADES
table is the most monolithic one in the whole context right now and it's more than desirable to split the entity up into sub classes.
I had expected simply overriding toString
to work from what I read, but this results in:
Caused by: Exception [EclipseLink-116] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: No conversion value provided for the value [M] in field [TRADES.TRADING_SECTOR].
Mapping: org.eclipse.persistence.mappings.DirectToFieldMapping[discriminator-->TRADES.TRADING_SECTOR]
Descriptor: RelationalDescriptor(com.company.project.model.Trade --> [DatabaseTable(TRADES)])
at org.eclipse.persistence.exceptions.DescriptorException.noFieldValueConversionToAttributeValueProvided(DescriptorException.java:1052)
at org.eclipse.persistence.mappings.converters.ObjectTypeConverter.convertDataValueToObjectValue(ObjectTypeConverter.java:140)
at org.eclipse.persistence.mappings.converters.EnumTypeConverter.convertDataValueToObjectValue(EnumTypeConverter.java:137)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getAttributeValue(AbstractDirectMapping.java:699)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.valueFromRow(AbstractDirectMapping.java:1299)
at org.eclipse.persistence.mappings.DatabaseMapping.readFromRowIntoObject(DatabaseMapping.java:1326)
Here's what the EclipseLink error docs at http://wiki.eclipse.org/EclipseLink_Exception_Error_Reference_%28ELUG%29 say:
ECLIPSELINK-00116: No conversion value provided for the value [{0}] in field [{1}].
Cause: The attribute conversion value for the fieldValue was not given in the object type mapping.
Action: Verify the field value, and provide a corresponding attribute value in the mapping.
Ah, yes. :-/
Q: What's the non-proprietary (JPA 2) way to solve this (if that's possible at all, without going too far into the hacking trenches)?
PS: It's not possible to change the DB values.