我想实现以下两个接口,并使用JPA和Hibernate将它们映射到数据库。
public interface IThing {
public IKey getId();
public void setId(IKey id);
}
public interface IKey {
public String getS();
public void setS(String s);
public Boolean getB();
public void setB(Boolean b);
}
所以Key
应该是一个有两个字段的对象。他们的名字和类型并不重要。重要的是,Key
是Thing
的复合键。
简单(或任何被认为对Java代码来说简单的实现):
@Entity
public class Thing implements IThing, java.io.Serializable {
@EmbeddedId
private IKey id;
public IKey getId() {
return this.id;
}
public void setId(IKey id) {
this.id = id;
}
}
@Embeddable
public class Key implements IKey, java.io.Serializable {
private String s;
private Boolean b;
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public Boolean getB() {
return b;
}
public void setB(Boolean b) {
this.b = b;
}
}
现在,您甚至不必使用它们,它们仅仅存在并且创建EntityManager似乎足以触发它:
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: example] Unable to configure EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:378)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:56)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:79)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:54)
at example.Main.main(Main.java:7)
... 6 more
Caused by: org.hibernate.AnnotationException: example.IKey has no persistent id property: example.Thing.id
at org.hibernate.cfg.AnnotationBinder.bindComponent(AnnotationBinder.java:2301)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2021)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:796)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:707)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:4035)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3989)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1398)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375)
at org.hibernate.ejb.Ejb3Configuration.buildMappings(Ejb3Configuration.java:1519)
at org.hibernate.ejb.EventListenerConfigurator.configure(EventListenerConfigurator.java:193)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:1100)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:282)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:366)
... 10 more
虽然我可以使用它(注意它没有实现IThing
并忽略IKey
接口)而没有错误:
@Entity
public class Thing2 implements java.io.Serializable {
@EmbeddedId
private Key id;
public Key getId() {
return this.id;
}
public void setId(Key id) {
this.id = id;
}
}
我没有找到任何方法来使用接口工作的版本。是否可以实现这两个接口并将生成的实现类转换为适当的JPA @Entity
和@EmbeddedId
?
(这可能与this other question有关,至少错误类似。)
答案 0 :(得分:0)
我不确定是否可能。
在我的反射经验中使用接口是不可能的,因为首先@Embeddable
应用于目标类而不是接口上,然后在许多情况下,许多框架的机制需要反射能够实例化类的特定类....对于接口来说当然是不可能的实例它因为Java中的接口是抽象类的特例。
我希望这可以帮到你