我有幾個實體具有基本的Long
ID和其他屬性。這些實體與另一個實體具有一對多關係,爲第一個實體保存不同的自定義(用戶輸入)翻譯。基本上有一個實體對,一個持有所有非翻譯內容,另一個持有文本屬性的多個翻譯。JPA與Java泛型
爲了減少代碼和註釋的重複,我想爲這些對之一中的每個實體創建一個抽象類。對於多種翻譯我創造了這樣一個類:
@MappedSuperclass
public abstract class CustomTranslations
{
@Id
protected Long id;
@Id
protected String locale;
}
對於主要實體我有這樣的:
@MappedSuperclass
public abstract class CustomTranslationsHolder<T extends CustomTranslations>
{
@OneToMany(fetch=FetchType.EAGER)
@JoinColumn(name="ID")
@MapKey(name="locale")
protected Map<String, T> translationsByLocale;
}
所以說實體對之一是Foo
。我想有這樣的:
@Entity
@Table(name="FOO_TRANSLATIONS")
public class FooTranslations extends CustomTranslations
{
private String title;
private String description;
....
}
這:
@Entity
public class Foo extends CustomTranslationsHolder<FooTranslations>
{
@Id
private Long id;
private String whatever;
private Integer blah;
...
public String getTitle(String locale)
{
return translationsByLocale.get(locale).getTitle();
}
}
這一切編譯得很好,但在服務器啓動時,我得到以下錯誤:
Exception Description: Neither the instance method or field named [locale] exists for the item class [class java.lang.Void], and therefore cannot be used to create a key for the Map.
at org.eclipse.persistence.exceptions.ValidationException.mapKeyNotDeclaredInItemClass(ValidationException.java:1332)
at org.eclipse.persistence.internal.queries.MapContainerPolicy.initializeKey(MapContainerPolicy.java:517)
at org.eclipse.persistence.internal.queries.MapContainerPolicy.getKeyType(MapContainerPolicy.java:438)
at org.eclipse.persistence.internal.jpa.metamodel.MapAttributeImpl.<init>(MapAttributeImpl.java:167)
at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.initialize(ManagedTypeImpl.java:1158)
at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.initialize(MetamodelImpl.java:459)
at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:111)
at org.eclipse.persistence.internal.jpa.metamodel.MetamodelImpl.<init>(MetamodelImpl.java:130)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.getMetamodel(EntityManagerSetupImpl.java:2566)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.getMetamodel(EntityManagerFactoryDelegate.java:592)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.getMetamodel(EntityManagerFactoryImpl.java:506)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:376)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:517)
at $Proxy8.getMetamodel(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:176)
at $Proxy12.getMetamodel(Unknown Source)
at org.springframework.data.jpa.repository.support.JpaEntityInformationSupport.getMetadata(JpaEntityInformationSupport.java:60)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getEntityInformation(JpaRepositoryFactory.java:149)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:87)
at org.springframework.data.jpa.repository.support.JpaRepositoryFactory.getTargetRepository(JpaRepositoryFactory.java:70)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:137)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:125)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:41)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
... 44 more
所以,它聽起來像它可以在T
上找到屬性locale
的地圖。它似乎應該知道T
是CustomTranslations
,因此知道CustomTranslations
上有一個locale
字段。
這是EclipseLink的問題嗎?還是有沒有辦法我可以這樣做?我很想知道Hibernate如何處理完全相同的代碼。任何信息或建議,將不勝感激。
您使用的是什麼版本的eclipselink? – Chris 2012-08-13 15:21:52
這是2.3.2 – dnc253 2012-08-13 20:17:25