Again I am not so sure that registerInParameter is any more readable than registerParameter passed ParameterMode.IN. Registering a parameter is registering a parameter is registering a parameter to para-quote Ms Stein. To me the one thing that would make sense to split them out that way is what I think you are thinking as well in your last bit. That is, if we were to do:
interface RegisteredParameter<T> { public Class<T> getJavaType(); public ParameterMode getMode(); } interface BindableRegisteredParameter<T> extends RegisteredParameter<T> { public void bind(T value); } Now the "split" methods make more sense: public <T> BindableRegisteredParameter<T> registerInParameter(int position, Class<T> type); public <T> BindableRegisteredParameter<T> registerInParameter(String name, Class<T> type); public <T> BindableRegisteredParameter<T> registerInOutParameter(int position, Class<T> type); public <T> BindableRegisteredParameter<T> registerInOutParameter(String name, Class<T> type); public <T> RegisteredParameter<T> registerOutParameter(int position, Class<T> type); public <T> RegisteredParameter<T> registerOutParameter(String name, Class<T> type); On Fri, Nov 16, 2012 at 2:28 PM, Gunnar Morling <gun...@hibernate.org> wrote: > IMO registerInParameter(String,Class) et al. read better than > registerParameter(int,Class,ParameterMode), while the latter might be a bit > simpler to use when writing the code. As code is more read than written, > optimizing the read use case might be the better option. But I agree that > six methods compared to two is quite a difference. > > Using different types for the different kinds of parameters would also avoid > the possibility of reading values from an IN parameter. > > > > 2012/11/16 Steve Ebersole <st...@hibernate.org> >> >> I can definitely see a benefit to your registerOutParameter over >> registerParameter if we wanted to return specific types. But aside >> from that, I am not so sure that having to know 3 different sets of >> methods to register parameters: >> >> registerInParameter(int,Class) >> registerInParameter(String,Class) >> registerInOutParameter(int,Class) >> registerInOutParameter(String,Class) >> registerOutParameter(int,Class) >> registerOutParameter(String,Class) >> >> is better than one set: >> >> registerParameter(int,Class,ParameterMode) >> registerParameter(String,Class,ParameterMode) >> >> Do you really think that is easier for a user? >> >> On Fri, Nov 16, 2012 at 12:52 PM, Gunnar Morling <gun...@hibernate.org> >> wrote: >> > Hi, >> > >> > FWIW, I'd prefer option #2 due to its type-safety. In #3 it's as you say >> > challenging to control when extract() can be invoked. >> > >> > Maybe you could offer dedicated methods for the different parameter >> > modes, >> > making client code a bit shorter: >> > >> > RegisteredParameter<Long> p1Param = >> > call.registerOutParameter( "p1", Long.class ); >> > >> > I tend towards that pattern if the number of possible enum values is >> > small, >> > as it should be the case here. >> > >> > --Gunnar >> > >> > >> > >> > 2012/11/16 Steve Ebersole <st...@hibernate.org> >> > >> >> I thought I had written about this before to the list, but maybe not. >> >> Anyway, I added much enhanced support for calling database functions >> >> and >> >> procedures to master. But this is just my initial swag and as far as I >> >> know my eyes are the only ones that have seen it. So I wanted to get >> >> some feedback. Feel free to give feedback on any/all aspects of that >> >> API, but there was one aspect in particular I was really wanting >> >> feedback: parameters. The concept of parameters, much like in queries, >> >> is split into 2 parts: declaration and usage. >> >> >> >> The initial impetus for this was the JPA 2.1 feature for supporting >> >> procedure calls. But I went a little different direction in our >> >> "native" support for this, the main difference being modeling the >> >> outputs as a separate thing from the call itself. I really like our >> >> API >> >> there better. >> >> >> >> The declaration of the call is modeled as >> >> org.hibernate.StoredProcedureCall (although I am thinking of moving >> >> away >> >> from "StoredProcedure" as the name base here since functions are >> >> supported as well; better name suggestions welcome). The outputs of >> >> the >> >> call execution is org.hibernate.StoredProcedureOutputs. >> >> >> >> To create a StoredProcedureCall, one simply calls one of the overloaded >> >> Session.createStoredProcedureCall methods passing in either (a) the >> >> func/proc name, (b) the func/proc name and any entity class(es) to map >> >> the results back to, (c) the func/proc name and any result set mapping >> >> name(s) to apply to the results. >> >> >> >> From there, parameters are declared/registered through the overloaded >> >> StoredProcedureCall#registerStoredProcedureParameter methods. Again, >> >> in >> >> retrospect not liking that name; should be declareParameter or >> >> registerParameter imo. Anyway, parameters can be treated as either >> >> positional or named. Named here has a little bit different meaning >> >> though, intending to name the arguments in the procedure/function >> >> definition. This is a feature defined by JDBC 3, although as I >> >> understand it not all drivers support it (aka, it can lead to >> >> SQLFeatureNotSupportedException). We can even know this a priori via >> >> DatabaseMetaData.html#supportsNamedParameters() to give better (and >> >> earlier!) exceptions. >> >> >> >> Anyway, currently registerStoredProcedureParameter returns back >> >> StoredProcedureCall for method chaining. We'll come back to that in a >> >> second... >> >> >> >> After parameters are registered, the values for IN and INOUT style >> >> parameters must be set/bound. Currently this is untyped because of the >> >> fact that registration does not return any "memento" with the typing >> >> information (the Java type is passed to the register method). After >> >> execution, the values from all INOUT and OUT parameters can be >> >> extracted, but again those extractions are untyped for the same reason. >> >> Which leads me to question whether we want to consider handling >> >> parameter values (whether in or out) in a typed manner is important. >> >> As >> >> an example, currently to extract an OUT parameter value you'd have: >> >> >> >> StoredProcedureCall call = >> >> session.createStoredProcedureCall("my_proc"); >> >> >> >> call.registerStoredProcedureParameter("p1",Long.class,ParameterMode.OUT); >> >> //maybe some other stuff... >> >> StoredProcedureOutputs outputs = call.getOutputs(); >> >> Long p1 = (Long) outputs.getOutputParameterValue("p1"); >> >> >> >> The alternative would be something like defining a typed >> >> RegisteredParameter contract: >> >> >> >> interface RegisteredParameter<T> { >> >> public Class<T> getParameterType(); >> >> public ParameterMode getMode(); >> >> } >> >> >> >> and then: >> >> >> >> StoredProcedureCall call = >> >> session.createStoredProcedureCall("my_proc"); >> >> RegisteredParameter<Long> p1Param = call.registerParameter( >> >> "p1", >> >> Long.class, >> >> ParameterMode.OUT >> >> ); >> >> //maybe some other stuff... >> >> StoredProcedureOutputs outputs = call.getOutputs(); >> >> Long p1 = outputs.getOutputParameterValue( p1Param ); >> >> >> >> >> >> Or maybe even: >> >> >> >> interface RegisteredParameter<T> { >> >> public Class<T> getParameterType(); >> >> public ParameterMode getMode(); >> >> >> >> public void bind(T value); >> >> public T extract(); >> >> } >> >> >> >> StoredProcedureCall call = >> >> session.createStoredProcedureCall("my_proc"); >> >> RegisteredParameter<Long> p1Param = call.registerParameter( >> >> "p1", >> >> Long.class, >> >> ParameterMode.OUT >> >> ); >> >> //maybe some other stuff... >> >> StoredProcedureOutputs outputs = call.getOutputs(); >> >> Long p1 = p1Param.extract(); >> >> >> >> The problem with this last one is managing when that 'extract' can be >> >> called... >> >> >> >> >> >> Anyway, thoughts? >> >> >> >> -- >> >> st...@hibernate.org >> >> http://hibernate.org >> >> _______________________________________________ >> >> hibernate-dev mailing list >> >> hibernate-dev@lists.jboss.org >> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev >> >> >> > _______________________________________________ >> > hibernate-dev mailing list >> > hibernate-dev@lists.jboss.org >> > https://lists.jboss.org/mailman/listinfo/hibernate-dev > > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev