我有一个像这样的抽象基类,并希望持久化子类的地图myMap
。
public abstract class MyGenericAbstractClass<V, E> {
Map<E, SomeClass<V>> myMap;
public Map<E, SomeClass<V>> getMyMap() {
return myMap;
}
由于我无法在抽象基类中注释通用映射(因为JPA需要具有表创建的类型信息),所以我决定覆盖子类中的getter并进行属性访问。
@Entity
@Access(AccessType.FIELD)
public class MyGenericClass extends MyGenericAbstractClass<VImpl, EImpl> {
@Id
@GeneratedValue
private Long id;
@Access(AccessType.PROPERTY)
@ManyToMany(cascade = CascadeType.PERSIST)
@MapKeyJoinColumn(name = "EIMPL_ID")
@JoinTable(name = "MapName")
@Override
public Map<EImpl, SomeClass<VImpl>> getMyMap() {
return myMap;
}
}
SomeClass.java
现在看起来像这样:
@Entity
public class SomeClass<V> {
@Id
@GeneratedValue
private Long id;
@OneToOne(targetEntity = jpa.test.minimalExample.VImpl.class, cascade = CascadeType.ALL)
V source;
@OneToOne(targetEntity = jpa.test.minimalExample.VImpl.class, cascade = CascadeType.ALL)
V target;
}
主:
EntityManagerFactory factory = Persistence.createEntityManagerFactory("Minimal");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
MyGenericClass mgc = new MyGenericClass();
SomeClass<VImpl> bar = new SomeClass<VImpl>();
EImpl foo = new EImpl();
Map<EImpl,SomeClass<VImpl>> mgcMap = new HashMap<EImpl,SomeClass<VImpl>>();
mgcMap.put(foo, bar);
mgc.setMyMap(mgcMap);
em.persist(foo);
em.persist(mgc);
em.getTransaction().commit();
EImpl
和VImpl
几乎是空的实体(只是ID)。
persistence.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="Minimal" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>jpa.test.minimalExample.SomeClass</class>
<class>jpa.test.minimalExample.MyGenericClass</class>
<class>jpa.test.minimalExample.MyGenericAbstractClass</class>
<class>jpa.test.minimalExample.VImpl</class>
<class>jpa.test.minimalExample.EImpl</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/simpleTest/;create=true" />
<property name="javax.persistence.jdbc.user" value="test" />
<property name="javax.persistence.jdbc.password" value="test" />
<property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
</properties>
</persistence-unit>
</persistence>
最后,这是我得到的错误:
[EL警告]:2016-05-27 13:55:12.675 - UnitOfWork(674882504) - 异常[EclipseLink-26] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DescriptorException异常 描述:尝试获取类型的变量[id]的值 来自对象的[java.lang.Long] [jpa.test.minimalExample.SomeClass]。指定的对象不是 声明基础字段的类或接口的实例。 内部异常:java.lang.IllegalArgumentException:无法设置 java.lang.Long字段jpa.test.minimalExample.VImpl.id到 jpa.test.minimalExample.SomeClass映射: org.eclipse.persistence.mappings.DirectToFieldMapping [ID - &GT; VIMPL.ID] 描述符:RelationalDescriptor(jpa.test.minimalExample.VImpl - &gt; [DatabaseTable(VIMPL)])
关于如何修复注释/修改我的类结构的任何建议,使得像这样的地图持久化的方式非常受欢迎。我也非常希望理解错误本身(及其原因)而不仅仅是得到一个解决方法,虽然现在我可以得到任何帮助。
提前谢谢