2010-11-18 2 views
6

У меня есть составной идентификатор, определенный в моей структуре классов, как показано ниже. К сожалению, я всегда получаю ошибку спящего режима, говорящее на не найден «part2»:Композитный ключ в JPA/Hibernate с унаследованным классом

«Свойство @IdClass не найдено в сущности MoreClass: part2»

Может кто-нибудь мне помочь в решении проблемы? (Или, по крайней мере, указать мне на полезные JPA/спящий режим док?)

@IdClass(ClassKey.class) 
@Entity 
public class MoreClass extends LessClass implements Serializable 
{ 
    @Id 
    String part1; 
} 

@MappedSuperclass 
public class LessClass implements Serializable 
{ 
    @Id 
    String part2; 
} 

public class ClassKey implements Serializable 
{ 
    String part1; 
    String part2; 
} 
+0

Как я могу получить некоторые взгляды, но нет ответа, я должен предположить, что это созвездие невозможно. Я просто не могу найти подсказки в документах ... – austrianuser

ответ

2

На самом деле врезался в same problem.

В:

@Override 
@Id 
public getPart2() { 
    return super.getPart2(); 
} 

Не похоже на работу, я сочту это ошибка. См. https://hibernate.atlassian.net/browse/HHH-9114.

+0

Я бы не назвал это ошибкой, см. Мой ответ ниже ... –

2

Указанный обходной путь для HHH-9114 bug от Michael работает, например. в моем случае, путем добавления к TwitterListedCount: (заметим, что оба @Idи@Type должны быть добавлены для типов пользователей по-прежнему работают)

// TODO: https://hibernate.atlassian.net/browse/HHH-9114 
@Override @Id 
public long getTwitterUserId() { 
    return super.getTwitterUserId(); 
} 

@Override @Id 
public DateTime getFetchTime() { 
    return super.getFetchTime(); 
} 

BTW, обходной путь имеет nasty side-effect HHH-9350 при использовании генерации схемы, его генерирует дублируют композитные колонны:

CREATE TABLE buzz.twitterlistedcount 
(
    id_fetchtime timestamp without time zone NOT NULL, 
    id_twitteruserid bigint NOT NULL, 
    _identifiermapper_fetchtime timestamp without time zone NOT NULL, 
    _identifiermapper_twitteruserid bigint NOT NULL, 
    listedcount integer NOT NULL, 
    CONSTRAINT twitterlistedcount_pkey PRIMARY KEY (id_fetchtime, id_twitteruserid) 
) 
WITH (
    OIDS=FALSE 
); 

Я попытался не использовать @MappedSuperclass на всех, но поколение неправильно схемы до сих пор происходит. BTW Я использую DefaultComponentSafeNamingStrategy, где может быть ошибка. Это, вероятно, другая ошибка, спросил Hibernate find with composite key. Invalid column name Exception

Надлежащий обходной путь предполагает добавление @Column(name=) вручную, что хорошо работает с генерацией схемы:

@Id 
@Basic() 
@Column(name="twitteruserid") 
private long twitterUserId = 0; 

@Id 
@Basic() 
@Column(name="fetchtime") 
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") 
private DateTime fetchTime = null; 

FYI, при использовании вместе с Spring Data JPA, это требуется для удалите @Id и @Type аннотации из MappedSuperclass. Если они не будут удалены, появятся ошибки ниже. Это не изменяет характер этой ошибки Hibernate, BTW.

org.springframework.data.mapping.model.MappingException: Ambiguous mapping! Annotation Id configured on field twitterUserId and one of its accessor methods in class TwitterFollowerCount! 
    at org.springframework.data.mapping.model.AnnotationBasedPersistentProperty.populateAnnotationCache(AnnotationBasedPersistentProperty.java:111) 
    at org.springframework.data.mapping.model.AnnotationBasedPersistentProperty.<init>(AnnotationBasedPersistentProperty.java:66) 
    at org.springframework.data.jpa.mapping.JpaPersistentPropertyImpl.<init>(JpaPersistentPropertyImpl.java:86) 
    at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.createPersistentProperty(JpaMetamodelMappingContext.java:67) 
    at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.createPersistentProperty(JpaMetamodelMappingContext.java:35) 
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.createAndRegisterProperty(AbstractMappingContext.java:449) 
    at org.springframework.data.mapping.context.AbstractMappingContext$PersistentPropertyCreator.doWith(AbstractMappingContext.java:427) 
    at org.springframework.util.ReflectionUtils.doWithFields(ReflectionUtils.java:607) 
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:295) 
    at org.springframework.data.mapping.context.AbstractMappingContext.addPersistentEntity(AbstractMappingContext.java:257) 
    at org.springframework.data.mapping.context.AbstractMappingContext.initialize(AbstractMappingContext.java:373) 
    at org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension$JpaMetamodelMappingContextFactoryBean.createInstance(JpaRepositoryConfigExtension.java:216) 
    at org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension$JpaMetamodelMappingContextFactoryBean.createInstance(JpaRepositoryConfigExtension.java:169) 
    at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134) 
    at org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension$JpaMetamodelMappingContextFactoryBean.afterPropertiesSet(JpaRepositoryConfigExtension.java:230) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549) 
    ... 40 more 
1

Из JPA спецификации:

Первичный ключ должен быть определен на классе сущностей, который является корнем иерархии сущностей или на отображенного суперкласса, который является (прямым или косвенным) суперкласс всех классов сущностей в иерархии сущностей. Первичный ключ должен быть определен ровно один раз в иерархии сущности.

Так что согласно JPA, вы не можете переопределить @Id. Я бы не назвал это ошибкой.

Хотя обходное решение, данное как ответ здесь, может работать, может случиться так, что для других фреймворков JPA это не сработает.

Смежные вопросы