views:

571

answers:

1

We have a set of interfaces, used as an API, and referenced from other modules. A set of concrete implementations of those interfaces, private to the "main" app module. These classes carry a number of annotations (JPA as well as XStream for XML serialization).

I've run into a problem. We have a user class which had a number of fields within it related to location. We'd like to roll those up into an Address class. We want the data (for now) to remain in the same table. The approach is an embedded class.

The problem is that the type signatures must only refer to other interfaces to satisfy the interfaces they implement.

When I try to persist a UserImpl, I get the exception:

org.hibernate.MappingException: Could not determine type for: com.example.Address, at table: User, for columns: [org.hibernate.mapping.Column(address)]

Example code:

interface User {
    int getId();
    String getName();
    Address getAddress();
}

@Entity
class UserImpl implements User {
    int id;
    String name;
    Address address;

    int getId() {
        return id;
    }

    void setId(int id) {
        this.id = id;
    }

    String getName() {
        return name;
    }

    String setName(String name) {
        this.name = name;
    }

    @Embedded
    Address getAddress() {
        return address;
    }

    void setAddress(Address address) {
        this.address = address;
    }
}


interface Address {
    String getStreet();
    String getCity();
    String getState();
    String getZip();
    String getCountry();
}

@Embeddable
class AddressImpl implements Address {
    String street;
    String city;
    String state;
    String zip;
    String country;

    public String getStreet() {
        return street;
    }

    public String getCity() {
        return city;
    }

    public String getState() {
        return state;
    }

    //... etc
}
+1  A: 

You can use the @Target Hibernate Annotation (which is a Hibernate-specific extension to the JPA annotations)

@Embedded
@Target( AddressImpl.class)
Address getAddress() {
    return address;
}
mtpettyp
Thanks, that is indeed a solution though I was hoping this could be done by using only JPA. Might help to know if this is possible with other JPA implementations.
Mark Renouf
Based on the exception you mentioned I assumed you were using Hibernate. Chances are if it's part of Hibernate Annotations it hasn't been added to the JPA spec yet.
mtpettyp
We are, but it would be nice to be vendor neutral where possible.
Mark Renouf