![](/img/trans.png)
[英]EclipseLink JPA issue with SINGLE_TABLE @Inheritance not inheriting
[英]EclipseLink + JPA + Generic Entity + SINGLE_TABLE Inheritance
我想知道在JPA中是否可以像我的案例PropertyBase中那样定义一个通用实体,并派生具体实体类(如ShortProperty和StringProperty),并将其与SINGLE_TABLE继承模式一起使用?
如果我尝试通过EntityManager提交新创建的ElementModel实例(请参见ElementModelTest),则始终会收到NumberFormatException,该错误无法将“值”正确转换为Short。 奇怪的是,如果我将下面的所有类都定义为测试用例类“ ElementModelTest”的内部静态类,则这似乎可以正常工作。
有什么想法我需要更改以使其正常工作吗?
我正在使用EclipseLink eclipselink-2.6.0.v20131019-ef98e5d。
public abstract class PersistableObject implements Serializable {
private String id = UUID.randomUUID().toString();
private Long version;
}
public abstract class PropertyBase<T> extends PersistableObject {
private String name;
private T value;
}
public class ShortProperty extends PropertyBase<Short> {
...
}
public class StringProperty extends PropertyBase<String> {
...
}
public class ElementModel extends PersistableObject {
private StringProperty name = new StringProperty();
private ShortProperty number = new ShortProperty();
}
public class ElementModelTest extends ModelTest<ElementModel> {
@Test
@SuppressWarnings("unchecked")
public void testSQLPersistence() {
final String PERSISTENCE_UNIT_NAME = getClass().getPackage().getName();
new File("res/db/test/" + PERSISTENCE_UNIT_NAME + ".sqlite").delete();
EntityManagerFactory factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();
for (int i = 0; i < 10; ++i) {
ElementModel device = new ElementModel();
device.setName("ElementModel: " + i);
device.setNumber((short) i);
em.persist(device);
}
em.getTransaction().commit();
em.close();
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd">
<mapped-superclass
class="PersistableObject">
<attributes>
<id name="id">
<column name="id" />
</id>
<version name="version" access="PROPERTY">
<column name="version" />
</version>
</attributes>
</mapped-superclass>
<entity class="PropertyBase">
<table name="PropertyBase" />
<inheritance />
<discriminator-column name="type"/>
<attributes>
<basic name="name">
<column name="name" />
</basic>
<basic name="value">
<column name="value" />
</basic>
</attributes>
</entity>
<entity class="StringProperty">
<discriminator-value>StringProperty</discriminator-value>
</entity>
<entity class="ShortProperty">
<discriminator-value>ShortProperty</discriminator-value>
</entity>
<entity class="ElementModel">
<table name="ElementModel" />
<inheritance />
<discriminator-column name="type"/>
<attributes>
<one-to-one name="name">
<join-column name="name" referenced-column-name="id" />
<cascade>
<cascade-all />
</cascade>
</one-to-one>
<one-to-one name="number">
<join-column name="number" referenced-column-name="id" />
<cascade>
<cascade-all />
</cascade>
</one-to-one>
</attributes>
</entity>
</entity-mappings>
您的问题是PropertyBase<T>
是一个实体,其字段value
是可持久的。 您的数据库需要将该字段类型映射为列类型,并且对于同一字段,您具有三个具有不同java类型的实体: PropertyBase<T>
是通用的,本身不知道其value
字段是什么类型, StringProperty
表示它是String和ShortProperty
表示这是一个Short。 因此,这是一个冲突。
为了克服此问题,您可以使字段value
瞬态,并且对于PropertyBase<T>
每个子类型(如StringProperty
),您都可以定义一个具有不同名称的新的persitable属性,例如。 StringProperty
将具有private String stringValue
, ShortProperty
将具有private Short shortValue
ShortProperty
,并且每个字段都将映射到不同的DB列。
PS:我无法解释为什么当您将所有类都设置为static inner
时它会起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.