Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Remove @Embeddable from classes already annotated with @Entity #6513

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

iyt-trifork
Copy link
Contributor

@iyt-trifork iyt-trifork commented Nov 26, 2024

Description

This pull request addresses an issue with classes in the HAPI FHIR JPA module that were annotated with both @Entity and @Embeddable. Such dual annotations are now explicitly disallowed by Hibernate as part of stricter validation introduced in recent versions (e.g., Hibernate 6.6.0 and later). This change ensures compliance with both JPA specifications and Hibernate’s new validation rules, resolving startup errors caused by conflicting annotations.


Background

Hibernate Stricter Validation

Starting with Hibernate 6.6.0, stricter validation rules were introduced to prevent classes from being annotated as both @Entity and @Embeddable. These two annotations serve distinct and incompatible purposes:

  • @Entity: Indicates that a class is a standalone entity with its own database table.
  • @Embeddable: Indicates that a class is not a standalone entity but instead is embedded within another entity’s table.

The presence of both annotations on a single class is logically inconsistent, leading to ambiguous behavior and runtime errors. Hibernate now throws an AnnotationException for such configurations.


Problem

The dual annotations caused the following error at application startup when using Hibernate 6.6.2:

Caused by: org.hibernate.AnnotationException: Invalid class annotated both '@Entity' and '@Embeddable': 'ca.uhn.fhir.jpa.model.entity.ResourceHistoryTag'
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getAnnotatedClassType(InFlightMetadataCollectorImpl.java:1276)
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.addClassType(InFlightMetadataCollectorImpl.java:1268)
	at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getClassType(InFlightMetadataCollectorImpl.java:1259)
	at org.hibernate.boot.model.internal.AnnotationBinder.buildInheritanceStates(AnnotationBinder.java:697)
	at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:247)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:281)
	at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:324)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502)
	at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:142)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:419)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:400)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1849)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1798)
	... 236 more

Solution

This pull request removes the @Embeddable annotation from all affected classes that were also annotated with @Entity. By doing so:

  1. Each class now clearly serves as a standalone entity.
  2. The conflict is resolved, allowing the application to start without errors.
  3. The change aligns with JPA specifications and Hibernate’s stricter enforcement.

The modifications ensure that all classes function correctly as standalone entities with proper mappings to their respective database tables.


References

Copy link

codecov bot commented Nov 26, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 83.46%. Comparing base (406db33) to head (942edaf).
Report is 103 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #6513      +/-   ##
============================================
- Coverage     83.54%   83.46%   -0.08%     
- Complexity    27432    27912     +480     
============================================
  Files          1707     1754      +47     
  Lines        106185   108306    +2121     
  Branches      13397    13596     +199     
============================================
+ Hits          88710    90396    +1686     
- Misses        11750    12066     +316     
- Partials       5725     5844     +119     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Removed @embeddable annotations from classes that were also annotated with @entity.
This resolves conflicts introduced by Hibernate's stricter validation, which disallows
a class from being both an entity (standalone table) and an embeddable (part of another entity).

The change aligns with JPA specifications and ensures compatibility with recent Hibernate versions
(e.g., stricter validation as per HHH-18172).
@iyt-trifork iyt-trifork force-pushed the fix/remove-entity-embeddable-conflict branch from 3a07bde to 942edaf Compare November 27, 2024 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant