1919import jakarta .persistence .OneToMany ;
2020import jakarta .persistence .OneToOne ;
2121import org .hibernate .AnnotationException ;
22+ import org .hibernate .AssertionFailure ;
2223import org .hibernate .MappingException ;
2324import org .hibernate .annotations .DiscriminatorFormula ;
2425import org .hibernate .annotations .Instantiator ;
@@ -146,33 +147,23 @@ private static Component createEmbeddable(
146147 PropertyData mapsIdProperty ,
147148 Class <? extends CompositeUserType <?>> compositeUserType ) {
148149 if ( isOverridden ) {
149- // careful: not always a @MapsId property, sometimes it's from an @IdClass
150- final String propertyName = mapsIdProperty .getPropertyName ();
151- final AnnotatedJoinColumns actualColumns = new AnnotatedJoinColumns ();
152- actualColumns .setBuildingContext ( context );
153- actualColumns .setPropertyHolder ( propertyHolder );
154- actualColumns .setPropertyName ( getRelativePath ( propertyHolder , propertyName ) );
155- //TODO: resetting the parent here looks like a dangerous thing to do
156- // should we be cloning them first (the legacy code did not)
157- for ( AnnotatedColumn column : columns .getColumns () ) {
158- column .setParent ( actualColumns );
150+ if ( compositeUserType != null ) {
151+ // I suppose this assertion is correct, but it might not be
152+ // Perhaps it was OK that we were just ignoring the CUT
153+ throw new AssertionFailure ( "CompositeUserType not allowed with @MapsId" );
159154 }
160- return bindEmbeddable (
161- inferredData ,
155+ return bindOverriddenEmbeddable (
162156 propertyHolder ,
163- entityBinder .getPropertyAccessor ( property ),
164- entityBinder ,
157+ inferredData ,
165158 isIdentifierMapper ,
166- context ,
167159 isComponentEmbedded ,
168- isId ,
160+ context ,
169161 inheritanceStatePerClass ,
170- mapsIdProperty .getClassOrElementName (),
171- propertyName ,
172- determineCustomInstantiator ( property , returnedClass , context ),
173- compositeUserType ,
174- actualColumns ,
175- columns
162+ property ,
163+ columns ,
164+ returnedClass ,
165+ isId ,
166+ mapsIdProperty
176167 );
177168 }
178169 else {
@@ -193,6 +184,44 @@ private static Component createEmbeddable(
193184 }
194185 }
195186
187+ private static Component bindOverriddenEmbeddable (
188+ PropertyHolder propertyHolder ,
189+ PropertyData inferredData ,
190+ boolean isIdentifierMapper ,
191+ boolean isComponentEmbedded ,
192+ MetadataBuildingContext context ,
193+ Map <ClassDetails , InheritanceState > inheritanceStatePerClass ,
194+ MemberDetails property ,
195+ AnnotatedColumns columns ,
196+ ClassDetails returnedClass ,
197+ boolean isId ,
198+ PropertyData mapsIdProperty ) {
199+ // careful: not always a @MapsId property, sometimes it's from an @IdClass
200+ final String propertyName = mapsIdProperty .getPropertyName ();
201+ final AnnotatedJoinColumns actualColumns = new AnnotatedJoinColumns ();
202+ actualColumns .setBuildingContext ( context );
203+ actualColumns .setPropertyHolder ( propertyHolder );
204+ actualColumns .setPropertyName ( getRelativePath ( propertyHolder , propertyName ) );
205+ //TODO: resetting the parent here looks like a dangerous thing to do
206+ // should we be cloning them first (the legacy code did not)
207+ for ( AnnotatedColumn column : columns .getColumns () ) {
208+ column .setParent ( actualColumns );
209+ }
210+ return bindOverriddenEmbeddable (
211+ inferredData ,
212+ propertyHolder ,
213+ isIdentifierMapper ,
214+ context ,
215+ isComponentEmbedded ,
216+ isId ,
217+ inheritanceStatePerClass ,
218+ mapsIdProperty .getClassOrElementName (),
219+ propertyName ,
220+ determineCustomInstantiator ( property , returnedClass , context ),
221+ actualColumns
222+ );
223+ }
224+
196225 static boolean isEmbedded (MemberDetails property , ClassDetails returnedClass ) {
197226 return property .hasDirectAnnotationUsage ( Embedded .class )
198227 || property .hasDirectAnnotationUsage ( EmbeddedId .class )
@@ -203,64 +232,42 @@ static boolean isEmbedded(MemberDetails property, TypeDetails returnedClass) {
203232 if ( property .hasDirectAnnotationUsage ( Embedded .class ) || property .hasDirectAnnotationUsage ( EmbeddedId .class ) ) {
204233 return true ;
205234 }
206-
207- final ClassDetails returnClassDetails = returnedClass .determineRawClass ();
208- return returnClassDetails .hasDirectAnnotationUsage ( Embeddable .class )
235+ else {
236+ final ClassDetails returnClassDetails = returnedClass .determineRawClass ();
237+ return returnClassDetails .hasDirectAnnotationUsage ( Embeddable .class )
209238 && !property .hasDirectAnnotationUsage ( Convert .class );
239+ }
210240 }
211241
212- private static Component bindEmbeddable (
242+ private static Component bindOverriddenEmbeddable (
213243 PropertyData inferredData ,
214244 PropertyHolder propertyHolder ,
215- AccessType propertyAccessor ,
216- EntityBinder entityBinder ,
217245 boolean isIdentifierMapper ,
218246 MetadataBuildingContext context ,
219247 boolean isComponentEmbedded ,
220- boolean isId , //is an identifier
248+ boolean isId , // is an identifier
221249 Map <ClassDetails , InheritanceState > inheritanceStatePerClass ,
222- String referencedEntityName , //is a component who is overridden by a @MapsId
250+ String referencedEntityName , // is a component which is overridden by a @MapsId
223251 String propertyName ,
224252 Class <? extends EmbeddableInstantiator > customInstantiatorImpl ,
225- Class <? extends CompositeUserType <?>> compositeUserTypeClass ,
226- AnnotatedJoinColumns columns ,
227- AnnotatedColumns annotatedColumns ) {
228- final Component component ;
229- if ( referencedEntityName != null ) {
230- component = createEmbeddable (
231- propertyHolder ,
232- inferredData ,
233- isComponentEmbedded ,
234- isIdentifierMapper ,
235- customInstantiatorImpl ,
236- context
237- );
238- context .getMetadataCollector ()
239- .addSecondPass ( new CopyIdentifierComponentSecondPass (
240- component ,
241- referencedEntityName ,
242- propertyName ,
243- columns ,
244- context
245- ) );
246- }
247- else {
248- component = fillEmbeddable (
249- propertyHolder ,
250- inferredData ,
251- propertyAccessor ,
252- !isId ,
253- entityBinder ,
254- isComponentEmbedded ,
255- isIdentifierMapper ,
256- context .getMetadataCollector ().isInSecondPass (),
257- customInstantiatorImpl ,
258- compositeUserTypeClass ,
259- annotatedColumns ,
260- context ,
261- inheritanceStatePerClass
262- );
263- }
253+ AnnotatedJoinColumns annotatedJoinColumns ) {
254+ final Component component = createEmbeddable (
255+ propertyHolder ,
256+ inferredData ,
257+ isComponentEmbedded ,
258+ isIdentifierMapper ,
259+ customInstantiatorImpl ,
260+ context
261+ );
262+ context .getMetadataCollector ()
263+ .addSecondPass ( new CopyIdentifierComponentSecondPass (
264+ component ,
265+ referencedEntityName ,
266+ propertyName ,
267+ annotatedJoinColumns ,
268+ context
269+ ) );
270+
264271 if ( isId ) {
265272 component .setKey ( true );
266273 checkEmbeddedId ( inferredData , propertyHolder , referencedEntityName , component );
0 commit comments