How to update a record using nhibernate - asp.net-mvc-3

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.

Related

Best way to assert that a value is not null

This is my method.
public boolean authenticateAndPollCallbackResult(BankIdAuthRequest bankIdAuthRequest) {
ResponseEntity<BankIdAuthResponse> authResponse = bankIdAuthentication(bankIdAuthRequest);
AbstractApplicationForm applicationForm = applicationFormRepository.findByToken(bankIdAuthRequest.getRefID());
try {
//Add new bankId authentication to database.
BankIdAuthenticationEntity bankIdAuthenticationEntity = new BankIdAuthenticationEntity();
bankIdAuthenticationEntity.setAbstractApplicationForm(applicationForm);
bankIdAuthenticationEntity.setAuthStatus(STATUS_PROGRESS);
bankIdAuthenticationEntity.setOrderReference(authResponse.getBody().getOrderRef());
bankIdAuthenticationEntity.setAutoStartToken(authResponse.getBody().getAutoStartToken());
Long bankIdAuthenticationId = bankIdAuthenticationRepository.save(bankIdAuthenticationEntity).getId();
BankIdAuthenticationEntity.AuthStatus authStatus;
do {
TimeUnit.MILLISECONDS.sleep(1500);
authStatus = getAuthStatus(bankIdAuthenticationId);
if (authStatus == BankIdAuthenticationEntity.AuthStatus.COMPLETED)
return true;
if (authStatus == BankIdAuthenticationEntity.AuthStatus.FAILED || authStatus == BankIdAuthenticationEntity.AuthStatus.NOT_ASSIGNED)
return false;
} while (authStatus == BankIdAuthenticationEntity.AuthStatus.PROGRESS);
} catch (InterruptedException e) {
log.error("InterruptedException: ", e);
Thread.currentThread().interrupt();
} catch (NullPointerException e) {
log.error("Either BankId API not responding correctly. Check server connection", e);
} catch (Exception e) {
log.error("Exception: Polling collect endpoint method failed", e);
}
return false;
}
Now SonarQube warns that these two lines can return null (and they can):
bankIdAuthenticationEntity.setOrderReference(authResponse.getBody().getOrderRef());
bankIdAuthenticationEntity.setAutoStartToken(authResponse.getBody().getAutoStartToken();
But i don't know what the best way to check for null is.
I tried using Objects.requireNonNull which throws a null and the i figured the null check would catch it but it just feel ugly and not correct.
Any suggestions or absolute correct ways of doing this that i might have missed?
The problem is that authResponse.getBody() can be null. Right?
In this cas you should check it before an either throw an exception or not execute the two lines:
if(authResponse.getBody() != null {
bankIdAuthenticationEntity.setOrderReference(authResponse.getBody().getOrderRef());
bankIdAuthenticationEntity.setAutoStartToken(authResponse.getBody().getAutoStartToken();
})
or
if(authResponse.getBody() == null {
throw new ....Exception();
}
And if the problem is that getOrderRef() or getAutoStartToken() could return null, you should check these values before and handle the cases when they are null.

why SaveChanges returned 2 instead of 1 since i used FirstOrDefault()

in the following code i want to Update record As you see SaveChanges() call when i get the First 'q' . but after run the code and get the first and only record for the one to Update, i get the success returned 2. the problem is after saveChanges i have 2 records in Sal Table. what should i write for define q until I get int success just 1 . and update clearly.
public static bool UpdateUser(User user)
{
try
{
var q = db.Users.Where(x => x.UserName == user.UserName).**FirstOrDefault**();
if (q != null)
{
q.Password = user.Password;
db.Users.Update(user);
int *success* = db.SaveChanges();
if (success == 1)
{
return true;
}
else
{
return false;
}
}
return false;
}
catch (Exception ex)
{
throw ex;
}
}
You're using "Connected scenario" of EF in your code.
in this case dbset that you fetching data from, tracking and EF listening to your changes for the data getting from dbset, then, after any changes to this datas when you using "SaveChanges" update them.
for resolve that You can use db.User.AsNoTracking().... to say to EF that i not needed to track dbset!

Oracle fom Nhibernate batch insert not work

<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.

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) {
}
}
}

ASP.NET Membership; something is calling dbo.aspnet_CheckSchemaVersion

I'm using ASP.NET Membership. I'm running it on a shared hosting site where I have an db schema I run things off.
In the scripts to generate the DB on the server I changed the schema from 'dbo' to this other schema; on the tables, views and SP's.
Thing work fine, with everything except the Membership; I'm able to contact the DB and pull up records.
However, the Membership-login fails with the message: "Could not find stored procedure 'dbo.aspnet_CheckSchemaVersion'."
This of course is called 'DBxx.aspnet_CheckSchemaVersion' in my database.
Where is this being called from and how can I make it call the correct schema?
It is being called in System.Web.Util.SecUtility and it is hardcoded. Unless you want to re-invent the wheel you need to re-provision your database. I have done it. Is not brain surgery but is a lot of work and the interest of segregating a database does not qualify in my book.
internal static void CheckSchemaVersion(ProviderBase provider, SqlConnection connection, string[] features, string version, ref int schemaVersionCheck)
{
if (connection == null)
{
throw new ArgumentNullException("connection");
}
if (features == null)
{
throw new ArgumentNullException("features");
}
if (version == null)
{
throw new ArgumentNullException("version");
}
if (schemaVersionCheck == -1)
{
throw new ProviderException(SR.GetString("Provider_Schema_Version_Not_Match", new object[] { provider.ToString(), version }));
}
if (schemaVersionCheck == 0)
{
lock (provider)
{
if (schemaVersionCheck == -1)
{
throw new ProviderException(SR.GetString("Provider_Schema_Version_Not_Match", new object[] { provider.ToString(), version }));
}
if (schemaVersionCheck == 0)
{
SqlCommand command = null;
SqlParameter parameter = null;
foreach (string str in features)
{
command = new SqlCommand("dbo.aspnet_CheckSchemaVersion", connection);
command.CommandType = CommandType.StoredProcedure;
parameter = new SqlParameter("#Feature", str);
command.Parameters.Add(parameter);
parameter = new SqlParameter("#CompatibleSchemaVersion", version);
command.Parameters.Add(parameter);
parameter = new SqlParameter("#ReturnValue", SqlDbType.Int);
parameter.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(parameter);
command.ExecuteNonQuery();
if (((parameter.Value != null) ? ((int) parameter.Value) : -1) != 0)
{
schemaVersionCheck = -1;
throw new ProviderException(SR.GetString("Provider_Schema_Version_Not_Match", new object[] { provider.ToString(), version }));
}
}
schemaVersionCheck = 1;
}
}
}
}

Resources