Ryan,

I agree, this would be a useful feature to have standardized by the JPA
specification.  My guess is that it would be too late to try to get
something into JPA 2.0, but one could recommend this feature for inclusion
in a future version of the spec.  Pinaki and Kevin (cc'd) participate in the
expert group so they may have recommendations for submitting feature
requests.

Currently, you can do the conversion yourself within your business logic (or
create separate entities or embeddables for the mappings), which can result
in an indirect and sometimes quirky OR mapping..  or you can use OpenJPA's
@Strategy extension to specify a custom value mapping handler. Here is an
example handler for UUID:

package strat;

import java.util.UUID;

import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ValueMapping;
import org.apache.openjpa.jdbc.meta.strats.AbstractValueHandler;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.ColumnIO;
import org.apache.openjpa.meta.JavaTypes;

public class UUIDValueHandler extends AbstractValueHandler {

    public Column[] map(ValueMapping vm, String name, ColumnIO io,
        boolean adapt) {
        Column col = new Column();
        col.setName(name);
        col.setJavaType(JavaTypes.STRING);
        return new Column[]{ col };
    }

    public boolean isVersionable() {
        return true;
    }

    /**
     * Convert the object value to its datastore equivalent.
     */
    public Object toDataStoreValue(ValueMapping vm, Object val,
        JDBCStore store) {
        if (val == null)
            return null;

        UUID uuid = (UUID) val;
        return uuid.toString();
    }

    /**
     *  Convert the datastore value to its object equivalent.
     */
    public Object toObjectValue(ValueMapping vm, Object val) {
        if (val == null)
            return null;

        String uuidStr = (String)val;
        return UUID.fromString(uuidStr);
    }
}

@Entity
public class EntityA {
...
    @Strategy("strat.UUIDValueHandler")
    private UUID uuid;
...
}

Using this custom value handler, UUID will be mapped internally to/from a
string type. In addition, the schema factory (if used) will create the
appropriate database column type(s).  The OpenJPA unit test suite has an
additional example usage of @Strategy which maps an object to/from multiple
database columns.  Search for @Strategy in
org.apache.openjpa.persistence.jdbc.annotations.NonstandardMappingEntity.

hth,
-Jeremy


On Mon, Mar 30, 2009 at 9:28 AM, Ryan Fogarty
<[email protected]>wrote:

> I use @XmlJavaTypeAdapter a lot to manipulate our data model for classes
> that just don't naturally fit into an XML model (like custom containers
> and the sort). Seems to be one of the most intuitive and powerful tools
> in JAXBs toolbox but I can't find anything like it in JPA 1 or 2.
>
> For instance, I can't seem to do the simplest thing with JPA such as
> take a java.util.UUID and have OpenJPA map it into a STRING.
>
> It looks like there is no chance of getting this into JPA 2 since they
> are in final draft. I just can't imagine such a useful tool *not*
> existing in a powerful API like JPA, so what gives? Have I missed
> something fundamental?
>
> Thank you,
> Ryan
>
>
>

Reply via email to