6

我在我的类结构上定义了一个复合 ID,如下所示。不幸的是,我总是收到一个休眠错误,抱怨找不到“part2”:

“在实体 MoreClass 中找不到 @IdClass 的属性:第 2 部分”

有人可以帮我解决问题吗?(或者至少指出我有用的 jpa/hibernate 文档?)

@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;
}
4

3 回答 3

3

Michael提到的HHH-9114 错误的解决方法可以工作,例如在我的情况下,通过添加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();
}

顺便说一句,当与模式生成一起使用时,解决方法有一个讨厌的副作用 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,但仍然会发生错误的模式生成。顺便说一句,我正在使用DefaultComponentSafeNamingStrategy这可能是错误所在。这可能是一个不同的错误,在Hibernate find with Composite key 中询问。列名无效异常

正确的解决方法是@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;

仅供参考,当与 Spring Data JPA 一起使用需要@Id@TypeMappedSuperclass. 如果不删除这些,则会出现以下错误。它不会改变这个 Hibernate bug 的性质,顺便说一句。

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
于 2014-08-19T07:24:36.950 回答
2

居然撞到了same problem

作为:

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

似乎有效,我认为这是一个错误。请参阅https://hibernate.atlassian.net/browse/HHH-9114

于 2010-12-23T11:32:06.647 回答
2

从 JPA 规范:

必须在作为实体层次结构根的实体类或映射超类上定义主键,该映射超类是实体层次结构中所有实体类的(直接或间接)超类。主键必须在实体层次结构中只定义一次。

因此,根据 JPA,您无法重新定义@Id. 我不会称这是一个错误。

尽管此处作为答案给出的解决方法可能有效,但对于其他 JPA 框架,它可能不起作用。

于 2015-12-08T15:41:17.690 回答