Given the class below does anyone know why EclipseLink implementation of JPA fails to map them to database entities? The following error is returned:
Entity class [class com.my.entity.Y] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
@Entity
@Access(AccessType.PROPERTY)
public interface Y {
void setId(Long id);
@Id
Long getId();
}
@Entity
public class Z implements Y {
long id;
@Override
public void setId(Long id) {
this.id = id;
}
@Override
public Long getId() {
return id;
}
}
Many thanks
EclipseLink does support querying and relationships to interfaces, but not currently in annotations.
To map the interface you can use a SessionCustomizer.
public class MyCustomizer implements SessionCustomizer {
public void customize(Session session) {
RelationalDescriptor descriptor = new RelationalDescriptor();
descriptor.setJavaInterface(Y.class);
descriptor.setAlias("Y");
session.addDescriptor(descriptor);
}
}
Mapping the interface allows querying on the interface which returns any of its subclasses, and defining relationships to the interface.
If the interface is used through the @VariableOneToOne annotation it will be automatically mapped.
Thanks to the person who linked to this question - it helped me come up with a solution to the issue as follows:
@Entity
public interface Y {
void setId(Long id);
@Id
Long getId();
}
// introduce intermediate abstract class which implements Y
@Entity
public abstract class X implements Y {
}
// make Z extends X
@Entity
public class Z extends X {
// use targetEntity = X.class where required
// leaving this class still free to use interface Y
long id;
@Override
public void setId(Long id) {
this.id = id;
}
@Override
public Long getId() {
return id;
}
}
You cannot annotate or query on an inferface. You can only query @Entity
classes, and these can only be placed on real classes, not interfaces. Use the @MappedSuperclass
annotation for inheritance.
See these: http://download.oracle.com/javaee/6/tutorial/doc/bnbqn.html#bnbqp and JPA doesn't support interfaces well..implications?