Does anyone know if NHibernate supports returning output parameters from stored procedures? I've had a search in the documentation but can't really find anything that confirms either way.
I was facing the same problem. NHibernate does not let you use stored procedures in this manner. But it does allow a way to make calls using the plain old ADO.NET API. Here's an example -
http://refactoringaspnet.blogspot.com/2009/06/how-to-use-legacy-stored-procedures-in.html
I can't officially confirm for you, but as far as I know, not directly. Stored procedure use in NHibernate is very specific to doing standard CRUD.
If you want to grab output paramaters (that are't the standard row count output parameter for INSERT, UPDATE, and DELETE), you could fall back to a different (or the standard) database access tools that give you direct access to SQL and the result set. (Assuming you can get by with bypassing NHibernate's cache. You'll want to make sure you flush NHibernate before you run the query too, etc.)
Related
I have an application in which I'd like to accept a user supplied SQL query from a front-end query builder (http://querybuilder.js.org/). That query eventually needs to make it's way to running in a postgres database to return a subset of data.
The query builder linked above can export SQL or a mongo query. I imagine using the mongo query is relatively safe, since I can add to it simply on the server:
query.owner_of_document = userId
to limit results (to documents owned by the user).
Whereas the SQL statement could potentially be hijacked in an injection attack if someone attempts to store a malicious string of SQL for execution.
Is directly accepting SQL from a client bad practice? How can I ensure the supplied SQL is safe?
Thanks!
Why do you need to accept an entire SQL statement?
Can you accept only parameters and then run a pre defined query?
There are loads of questions/answers on SO relating to SQL injection and using parameters is a first step in avoiding injection attacks, such as "Are Parameters really enough to prevent Sql injections?"
But I think this answer to a different question sums things up well:
Don't try to do security yourself. Use whatever trusted, industry
standard library there is available for what you're trying to do,
rather than trying to do it yourself. Whatever assumptions you make
about security, might be incorrect. As secure as your own approach may
look ... there's a risk you're overlooking something and do you
really want to take that chance when it comes to security?
Im designing a UWP app that uses an SQLite database to store its information. From previous research I have blearnt that using the SQLite function SQLiteConnection.Update() and SQLiteConnetion.Insert() functions are safe to use as the inputs are sanitised before entering in the database.
The next step I need to do is sync that data with an online database - in this case SQL Server - using a service layer as my go between. Given that the data was previously sanitised by the SQLite database insert, do I still need to parameterise the object values using the service layer before they are passed to my SQL Server database?
The simple assumption says yes because, despite them being sanitised by the SQLite input, they are technically still raw strings that could have an effect on the main database if not parameterised when sending them there.
Should I just simply employ the idea of "If in doubt, parameterise" ?
I would say that you should always use SQL parameters. There are a few reasons why you should do so:
Security.
Performance. If you use parameters the reuse of execution plans could increase. For details see this article.
Reliability. It is always easier to make a mistake if you build SQL commands by concatenating strings.
When I troubleshoot a large .NET app which uses only stored procedures, I capture the sql which includes the SP name from SQL Server Profiler and then it's easy to do a global search for the SP in the source files and find the exact line which produced the SQL.
When using Entity Framework, this is not possible due to the dynamic creation of SQL statements. However there are times when I capture some problematic sql statements from production and want to know where in the code they were generated from.
I know one can have EF generate logs and tracing on demand. This probably would be taxing for a busy server and produces too much logs. I read some stuff about using mini profiler but not sure if it fits my needs as I don't have access to the production server. I do however have access to attach SQL Server Profiler to the database server.
My idea is to find a way to have EF attach/inject a unique code to the generated SQL but it doesn't affect the outcome of the SQL. I can then use it to cross reference it to the line of code which injected it into the SQL. The unique code is static which means a unique static code is used for every EF linq statement. Maybe sent as a dummy sql or a comment along with the sql statement.
I know this will add some extra traffic but in my case, it will add extra flexibility and cut a lot of troubleshooting time.
Any ideas of how to do this or any alternatives?
One very simple approach would be to execute something via ExecuteStoreCommand(): Refresh data from stored procedure. I'm not sure if you can "execute" just a comment, but at the very least you should be able to do something like:
ExecuteStoreCommand("DECLARE #MyTag VARCHAR(100) = 'some_unique_id';");
This is very simple, but you would have to find the association in two steps:
Get the SessionID (i.e. SPID) from poorly performing query in SQL Server Profiler
Search the Profiler entries for the prior SQL statement for that same SPID
Another option that might be a little more complicated but would remove that additional step when it comes to making that association is to "intercept" the commands before they get executed and inject a comment with your unique id. Please see the following S.O. Answer for details. You shouldn't need the full extent of what they did, but even if you do, it seems like all of the code (or all the relevant stuff) is there:
Adding a query hint when calling Table-Valued Function
By the way, this situation is a point in favor of using Stored Procedures instead of an ORM. And, what do you expect to be able to do in terms of performance tuning once you do find the offending app code? (another point in favor of using Stored Procedures instead of an ORM ;-).
We're using NHibernate with Memcache as the second level cache. Occasionally there is a need for more advanced queries or bulk query operations. From the book Nhibernate in Action they recommend the following:
"It’s our view that ORM isn’t suitable for mass-update (or mass-delete) operations. If
you have a use case like this, a different strategy is almost always better: call a stored
procedure in the database, or use direct SQL UPDATE and DELETE statements for that
particular use case."
My concern is that queries against the underlying database do not reflect in the cache (at least until cache expiry) and I was wondering if anyone has come up with any effective strategies for mixing and matching NHibernate with custom SQL statements?
Is there any way of getting say a bulk Update statement (executed with custom sql) to reflect in the second level cache? I am aware of being able to manually evict, but this removes the items from cache and thefore increases hits on the database.
Does the community have any solutions that have been found to be effective in dealing with this problem?
As far as I know there is no method to keep the 2nd level cache up to date with massupdates. But you can partially evict the cache as described in: http://www.nhforge.org/doc/nh/en/index.html#performance-sessioncache.
I am using Hibernate in my project and there is a certain scenario where I want to use the uniqueResult() method on the org.hibernate.SQLQuery class to perform native SQL INSERT and UPDATE operations.
I did try using the executeUpdate() method on the same class. But I get an error saying that they are used for HQL updates only.
Please advice if this is effective and reliable way of ensuring data being saved/updated in the database.
session.createSQLQuery() is for querying, not manipulation. If you want to do raw SQL insert, use session.connection() and straight JDBC code.
Not sure why you need this exactly but I'd also suggest to check 16.3. Custom SQL for create, update and delete.