| There is nothing in the API that prevents an embeddable parameter to be mapped for a stored procedure. For example, with Address is an embeddable: {{ @NamedStoredProcedureQuery( name = "User.findAddressById", resultClasses = User.class, procedureName = "PROC", parameters = { @StoredProcedureParameter(mode = ParameterMode.IN, name = "ID_PARAM", type = Integer.class), @StoredProcedureParameter(mode = ParameterMode.OUT, name = "ADDRESS_PARAM", type = Address.class) } ) }} When Hibernate tries to create the stored procedure, the following exception is thrown: {{ java.lang.IllegalArgumentException: Type cannot be null at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.setHibernateType(AbstractParameterRegistrationImpl.java:187) at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.<init>(AbstractParameterRegistrationImpl.java:124) at org.hibernate.procedure.internal.AbstractParameterRegistrationImpl.<init>(AbstractParameterRegistrationImpl.java:97) at org.hibernate.procedure.internal.NamedParameterRegistration.<init>(NamedParameterRegistration.java:35) at org.hibernate.procedure.internal.ProcedureCallImpl.<init>(ProcedureCallImpl.java:235) at org.hibernate.procedure.internal.ProcedureCallMementoImpl.makeProcedureCall(ProcedureCallMementoImpl.java:65) at org.hibernate.internal.SessionImpl.createNamedStoredProcedureQuery(SessionImpl.java:3636) at org.hibernate.jpa.test.procedure.StoreProcedureOutParameterByNameTest.testNamedBasicAndEmbeddableOutParameters(StoreProcedureOutParameterByNameTest.java:127) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.hibernate.testing.junit4.ExtendedFrameworkMethod.invokeExplosively(ExtendedFrameworkMethod.java:45) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) at org.junit.internal.runners.statements.FailOnTimeout$StatementThread.run(FailOnTimeout.java:74) }} The Hibernate type for the embeddable is null because the ParameterMemento constructor passes the value returned by sessionFactory.getTypeResolver().heuristicType( type.getName() ), which returns null. In addition the following needs to be resolved to support this improvement:
- for a named embeddable parameter, some strategy needs to be used to generate parameter names for the embeddable's sub-attributes (and sub-subattributes, etc.); these names must match the parameter names defined for the stored procedure in the database;
- for a positional embeddable parameter, some strategy needs to be used so that the order of the embeddable's sub-attributes (and sub-subattributes, etc.) matches the order of the parameters defined for the stored procedure in the database (is this possible)?
|