Composite Key in JPA / Hibernate with inherited class

后端 未结 3 1800
臣服心动
臣服心动 2021-02-04 18:12

i have a composite id defined on my class structure as below. Unfortunatly i always get a hibernate error that complains on the not found \"part2\":

\"Property of @IdCla

相关标签:
3条回答
  • 2021-02-04 18:55

    Actually bumped into the same problem.

    As:

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

    Does seem to work, I would deem it a bug. See https://hibernate.atlassian.net/browse/HHH-9114.

    0 讨论(0)
  • 2021-02-04 19:08

    From the JPA spec:

    The primary key must be defined on the entity class that is the root of the entity hierarchy or on a mapped superclass that is a (direct or indirect) superclass of all entity classes in the entity hierarchy. The primary key must be defined exactly once in an entity hierarchy.

    So according to JPA you can't redefine the @Id. I wouldn't call this a bug.

    Although the workaround given as answer here might work, it may happen that for other JPA frameworks it doesn't work.

    0 讨论(0)
  • 2021-02-04 19:19

    The mentioned workaround for HHH-9114 bug by Michael works, e.g. in my case by adding to TwitterListedCount : (note that both @Id and @Type must be added for user types to still work)

    // 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, the workaround has a nasty side-effect HHH-9350 when used with schema generation, it generates duplicate composite columns:

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

    I tried to not use @MappedSuperclass at all, but the wrong schema generation still happens. BTW I'm using DefaultComponentSafeNamingStrategy which may be where the bug lies. This is probably a different bug, asked in Hibernate find with composite key. Invalid column name Exception

    The proper workaround involves adding @Column(name=) manually, which works well with schema generation:

    @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, when used together with Spring Data JPA, it's required to remove the @Id and @Type annotations from the MappedSuperclass. If these are not removed, there will be errors bellow. It doesn't change the nature of this Hibernate bug, 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
    
    0 讨论(0)
提交回复
热议问题