I am using hibernate and annotations for ORM. I have interfaces for all beans and I am using targetEntity for relationships: hibernate cannot derive the type because the getter returns an interface rather than a bean.
I get a MappingException (could not determine type) for embedded beans.
@Entity(name="FieldBean")
public class FieldBean implements Field {
...
}
@Embeddable
public class FacetBean implements Facet {
...
@ManyToOne(targetEntity = FieldBean.class)
@JoinColumn(name = "field_id")
public Field getField() {
return field;
}
}
@Entity(name = "Chart")
public class ChartBean implements Chart {
@Embedded
@AssociationOverride(
name = "field",
joinColumns = @JoinColumn(name = "category_facet_field_id")
)
public Facet getCategoryFacet() {
return categoryFacet;
}
}
I get the MappingException: Could not determine type for: Field, at table: chart, for columns: [org.hibernate.mapping.Column(field)]
Using beans instead of interfaces for property and getter/setter declarations solves the problem, but I would like to stick to using interfaces. Using beans for property declarations alone does not solve the problem.
Could anyone point me in the right direction ?
I have used a workable solution to this for a while now, but it includes a minor case of vendor lock-in. I have found no way of doing this with JPA annotations only, but there is a Hibernate-specific annotation @Target
that does the trick. I have done something like you have, with the expected results. However, I didn't use your other annotations so I can't guarantee it will turn out to work as you expect.
Nothing strange going on in the Embeddable classes:
public interface PointsInt extends Serializable {
int offensivePoints();
int defensivePoints();
}
@Embeddable
public class Points implements PointsInt {
private int def;
private int off;
public int offensivePoints() { return off; }
public int defensivePoints() { return def; }
}
But in the consuming class, we use Hibernate's @Target
:
import javax.persistence.*;
import org.hibernate.annotations.Target;
@Entity
public class Series extends LongIdEntity implements Serializable {
@Embedded
@Target(Points.class)
private PointsInt points;
// I prefer to declare my annotations on fields rather than methods
}
Result:
mysql> describe series;
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| def | int(11) | YES | | NULL | |
| off | int(11) | YES | | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
3 rows in set (0.12 sec)
My past using jpa told me not to use inheritance. No mapped superclasses, no interfaces, etc ... simply entities with members. i worked with hibernate as well as eclipselink and both have really, really problems with inheritance. It is relly difficulty to write a persistence layer with jpa that supports more than one provider, as there are so many bugs all these providers. keep it as simple as possible. don't use any "special" features. i assure you, when trying to change the provider or simply running a software on different applications servers like jboss (hibernate) or glassfish/weblogic (eclipse/top link), you can be glad when having a most simply persistence layer that uses as little features as possible. i don't know if this is a bug, but i'd assume it is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With