2010-11-18 10 views
6

Tengo una ID compuesta definida en la estructura de mi clase como se muestra a continuación. Desafortunadamente yo siempre consigo un error de hibernación que se queja en la que no se encuentra "parte 2":Clave compuesta en JPA/Hibernar con clase hereditaria

"Propiedad de @IdClass que no se encuentran en la entidad MoreClass: parte 2"

Puede alguien me ayude en solucionar el problema? (O por lo menos me punto en una APP útiles/hibernación doc?)

@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

Como obtengo algunas vistas, pero ninguna respuesta, debería suponer, que esta constelación no es posible. Simplemente no puedo encontrar una pista en los documentos ... – austrianuser

Respuesta

2

En realidad topamos con la same problem.

como:

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

parece funcionar, me lo considera un error. Ver https://hibernate.atlassian.net/browse/HHH-9114.

+0

No lo llamaría un error, vea mi respuesta a continuación ... –

2

La solución mencionada para HHH-9114 bug de Michael works, p. Ej. en mi caso, añadiendo a TwitterListedCount: (tenga en cuenta que tanto @Idy@Type hay que añadir para tipos de usuario que todavía funcionan)

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

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

Por cierto, la solución tiene un nasty side-effect HHH-9350 cuando se utiliza con la generación esquema, se genera duplicar columnas compuestas:

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 
); 

traté de no utilizar @MappedSuperclass en absoluto, pero la generación de esquemas mal todavía sucede. Por cierto, estoy usando DefaultComponentSafeNamingStrategy que puede ser donde se encuentra el error. Esto es probablemente un error diferente, se le preguntó en Hibernate find with composite key. Invalid column name Exception

La solución adecuada consiste en añadir @Column(name=) manualmente, lo que funciona bien con la generación de esquemas:

@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, cuando se utiliza junto con Spring Data JPA, que se requiere para elimine las anotaciones @Id y @Type del MappedSuperclass. Si no se eliminan, habrá errores a continuación. Es no cambia la naturaleza de este error de 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

De la especificación JPA:

La clave primaria debe ser definido en la clase de entidad que es la raíz de la jerarquía entidad o en una superclase asignada que es un (directa o indirecta) superclase de todas las clases de entidad en la jerarquía de entidades. La clave principal debe definirse exactamente una vez en una jerarquía de entidades.

De acuerdo con JPA no puede redefinir el @Id. Yo no llamaría esto un error.

Aunque la solución dada como respuesta aquí podría funcionar, puede suceder que para otros marcos JPA no funcione.

Cuestiones relacionadas