Oracle fom Nhibernate batch insert not work - oracle

<property name="adonet.batch_size">100</property>
here is some code:
using (var session = SessionFactory.NHSessionFactory.OpenStatelessSession())
{
using (var tx = session.BeginTransaction())
{
try
{
foreach (var entity in entities)
{
session.Insert(entity);
}
tx.Commit();
}
catch (Exception ex)
{
}
}
}
the same code,and the same config.but oracle is not batch insert.
I try to add
<property name="adonet.factory_class">NHibernate.AdoNet.OracleDataClientBatchingBatcherFactory,NHibernate</property>
throw null object.

Stateless sessions do not use batching.
That's it.

Related

Oracle database over ODBC converts non-english characters to question marks

I am working on retrieving data from an Oracle data source, however I am having issues with non-english characters being replaced with question marks. Some background:
I am pulling data from an Oracle view whose columns are defined as VARCHAR2
When accessing said view through Oracle SQL Developer, the results display properly
I have attempted to update my System.Web.Odbc to the latest version to no avail
I am aware that the console does not properly display certain Unicode characters, but even viewing the raw data using breakpoints shows said characters replaced with '?'
Here is a runnable example with some specific implementation details removed:
using System;
using System.Data;
using System.Data.Odbc;
namespace OdbcTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Trying ODBC Connection");
DataTable odbcData = GetData("SELECT NAME as name FROM SYSADM.[ViewName] WHERE TRUNC(sysdate) - to_date(HIRE_DT) BETWEEN 0 AND 20");
Console.WriteLine(odbcData.Rows.Count.ToString() + "rows extracted.");
foreach (DataRow dataRow in odbcData.Rows)
{
foreach (var item in dataRow.ItemArray)
{
Console.WriteLine(item);
}
}
Console.ReadKey();
}
public static DataTable GetData(string SQLStatement)
{
try
{
using (System.Data.Odbc.OdbcConnection connection = new OdbcConnection([DSN Details]))
{
DataSet ds = new DataSet();
OdbcCommand command = new OdbcCommand(SQLStatement, connection);
OdbcDataAdapter adapter = new OdbcDataAdapter(command);
command.CommandTimeout = 600;
connection.Open();
adapter.Fill(ds);
connection.Close();
return ds.Tables[0];
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}

How to roll back queries in C#?

I have list of delete queries & I execute them with this code:
using (var ctx = new ApplicationDbContext(schemaName))
{
foreach (var item in queries)
{
ctx.Database.ExecuteSqlCommand(item);
}
}
I want to commit all the delete queries, but I want to roll back if there is some error in any of the queries.
How to do roll back in the above scenario?
Try to use TransactionScope
using System.Transactions;
try
{
using (var scope = new TransactionScope())
{
using (var ctx = new ApplicationDbContext(schemaName))
{
foreach (var item in queries)
{
ctx.Database.ExecuteSqlCommand(item);
}
}
scope.Complete();
}
}
catch (Exception ex)
{
}

ResultSet doesn't return values for DB2, but it return values if I try to do it manualy

I'm trying to get values from resulset, but it return nothing.
When i'm trying to do it through plain sql it return some values.
List<String> res = new ArrayList<String>();
try {
String query = "SELECT COLUMN_NAME FROM idoc.columns_to_show where user = ? "
+ DAO.DB2_UR_POSTFIX;
Connection connection = Properties.getDocsConnection();
try {
PreparedStatement pr = connection.prepareStatement(query);
try {
pr.setString(1, user.getDomainName());
ResultSet rs = pr.executeQuery();
try {
while (rs.next()) {
res.add(rs.getString("COLUMN_NAME"));
}
} finally {
rs.close();
}
} finally {
pr.close();
}
} finally {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return res;
Don't use column name "user" it is reserved name for DB2 database.
Therefore I couldn't find any result.

DD anomaly, and cleaning up database resources: is there a clean solution?

Here's a piece of code we've all written:
public CustomerTO getCustomerByCustDel(final String cust, final int del)
throws SQLException {
final PreparedStatement query = getFetchByCustDel();
ResultSet records = null;
try {
query.setString(1, cust);
query.setInt(2, del);
records = query.executeQuery();
return this.getCustomer(records);
} finally {
if (records != null) {
records.close();
}
query.close();
}
}
If you omit the 'finally' block, then you leave database resources dangling, which obviously is a potential problem. However, if you do what I've done here - set the ResultSet to null outside the **try** block, and then set it to the desired value inside the block - PMD reports a 'DD anomaly'. In the documentation, a DD anomaly is described as follows:
DataflowAnomalyAnalysis: The dataflow analysis tracks local definitions, undefinitions and references to variables on different paths on the data flow.From those informations there can be found various problems. [...] DD - Anomaly: A recently defined variable is redefined. This is ominous but don't have to be a bug.
If you declare the ResultSet outside the block without setting a value, you rightly get a 'variable might not have been initialised' error when you do the if (records != null) test.
Now, in my opinion my use here isn't a bug. But is there a way of rewriting cleanly which would not trigger the PMD warning? I don't particularly want to disable PMD's DataFlowAnomalyAnalysis rule, as identifying UR and DU anomalies would be actually useful; but these DD anomalies make me suspect I could be doing something better - and, if there's no better way of doing this, they amount to clutter (and I should perhaps look at whether I can rewrite the PMD rule)
I think this is clearer:
PreparedStatement query = getFetchByCustDel();
try {
query.setString(1, cust);
query.setInt(2, del);
ResultSet records = query.executeQuery();
try {
return this.getCustomer(records);
} finally {
records.close();
}
} finally {
query.close();
}
Also, in your version the query doesn't get closed if records.close() throws an exception.
I think that DD anomaly note is more bug, than a feature
Also, the way you free resources is a bit incomplete, for example
PreparedStatement pstmt = null;
Statement st = null;
try {
...
} catch (final Exception e) {
...
} finally {
try{
if (pstmt != null) {
pstmt.close();
}
} catch (final Exception e) {
e.printStackTrace(System.err);
} finally {
try {
if (st != null) {
st.close();
}
} catch (final Exception e) {
e.printStackTrace(System.err);
}
}
}
moreover this is not right again, cuz you should close resources like that
PreparedStatement pstmt = null;
Throwable th = null;
try {
...
} catch (final Throwable e) {
<something here>
th = e;
throw e;
} finally {
if (th == null) {
pstmt.close();
} else {
try {
if (pstmt != null) {
pstmt.close();
}
} catch (Throwable u) {
}
}
}

How to update a record using nhibernate

Hi i am working in MVC3 and for database communication i am using NHIBERNATE
I am getting a problem in updating a record.
Firstly session.SaveorUpdate does not work
Then i tried the following thing but this also does not work:(
public bool EditParentStudent(ParentStudent parentstudent)
{
log.Debug("Start");
if (parentstudent == null)
{
throw new ArgumentNullException("parentstudent");
}
ISession session = DataAccessLayerHelper.OpenWriterSession();
ITransaction transaction = session.BeginTransaction();
bool saved = false;
try
{
session.SaveOrUpdate(parentstudent);
transaction.Commit();
saved = true;
}
catch (SessionException ex)
{
if (transaction != null && transaction.IsActive)
transaction.Rollback();
log.Error(ex);
}
finally
{
if (transaction != null)
transaction.Dispose();
if (session != null && session.IsConnected)
session.Close();
}
log.Debug("End");
return saved;
}
If your entity is persistent you don't need to update it explicitly.
using (var session = sessionFactory.OpenSesion())
using (var tx = session.BeginTransaction())
{
// perform your insert here
tx.Commit();
}
Assuming that your mapping is ok, if you are using mvc3 then you should put code inside controller, for example
public ActionResult Edit(ParentStudent parentstudent)
{
//open session
// open transaction
//found existing data
var data = session.Query<ParentStudent>().Where(x=>x.Id == parentstudent.Id).FirstOrDefault();
session.SaveOrUpdate(data);
transaction.Commit();
//close transaction
//close session
return View();
}
maybe is better to put this code inside try catch block and to catch possible exception, but I was trying to make it simple as possible.
Hope this helps.

Resources