Friday, September 11, 2009

NHibernate.AssertionFailure was unhandled possible nonthreadsafe access to session

One of our project we faced this issue, my teammates and i worked to reproduce this.

How to Reproduce -

namespace NHibernatePossibleThreadIssue
{
public class Program
{
private static ISession Session;

public static void Main(string[] args)
{
Configuration conf = new Configuration();
IDictionary properties = new Dictionary
{
{"hibernate.connection.driver_class", "NHibernate.Driver.OracleClientDriver"},
{"hibernate.connection.connection_string", "Data Source=XE; user ID=sso; Password=sso"},
{"hibernate.dialect", "NHibernate.Dialect.Oracle9Dialect"},
{"hibernate.show_sql", "true"}
};


conf.SetProperties(properties);
conf.AddClass(typeof (SomeDomain));
conf.AddClass(typeof (SomeChild));
ISessionFactory factory = conf.BuildSessionFactory();

Session = factory.OpenSession();
LoadInSessionTwice();


//ConfigureCastle();

//TryThreading();
Console.ReadKey();


}

private static void LoadInSessionTwice()
{

SomeDomain domain = Session.Load(91286L);
IQuery query = Session.CreateQuery(" from SomeDomain d where d.desc= :desc ");
query.SetParameter("desc", "helloworld");
SomeDomain evicted = query.List()[0];

Session.Evict(evicted);
Session.Flush();

}

Mapping and domain classes

public class SomeDomain
{
public long id { get; set; }
public string desc { get; set; }

private SomeChild child;

public SomeChild Child
{
get
{
if (child == null)
child = new SomeChild {Domain = this};

return child;
}
set { child = value; }
}

}

public class SomeChild {

public long Id { get; set; }

public SomeDomain Domain { get; set;}

public string description { get; set; }

}

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernatePossibleThreadIssue">
<class name="NHibernatePossibleThreadIssue.SomeDomain" lazy="false" table="SOMEDOMAIN">
<id name="id" type="long" column="ID" unsaved-value = "0" >
<generator class="native">
<param name="sequence">COR_SEQ</param>
</generator>
</id>
<property name="desc" column="text"/>
<one-to-one name="Child"
class="NHibernatePossibleThreadIssue.SomeChild" cascade="all-delete-orphan"/>

</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernatePossibleThreadIssue">
<class name="NHibernatePossibleThreadIssue.SomeChild" lazy="false" table="SOMECHILD">
<id name="Id" column="SD_ID">
<generator class="foreign">
<param name="property">Domain</param>
</generator>
</id>
<one-to-one name="Domain" class="NHibernatePossibleThreadIssue.SomeDomain" constrained="true"/>
<property name="description"/>
</class>
</hibernate-mapping>

Thursday, September 10, 2009

NHibernate and Session Flushing

We have some bad code in our application which was using same hibernate session across multiple threads. We were not flushing the session, but data was still getting saved in database.

The reason was when first thread use to save, data was in hibernate session, but when second thread was trying to read a data using same hibernate session, hibernate was flushing the data in its session, thus it was not possible to find this error from UI as first requests data even though not saved in DB, will be seen in second request because second request is going to make hibernate session flush the data as it was read data request.

Learning Scala

We had first hands on session on Scala 10 Sept,2009, a functional programming language, here is simple example which adds all numbers upto 1000 which are multiple of 3 or 5.

package test

object Example1 extends Application {

val answers =(1 until 1000).filter {eachNumber => eachNumber%3==0 || eachNumber%5==0}
val sum = answers.foldLeft(0) { _+ _ }
println(sum)

}

Tuesday, September 8, 2009

Using RSA private-public key with c# app for decyption(server) and java app for encryption(client)

Using RSACryptoServiceProvider (c#) we created public and private key pair. Public key is then used by Java client to encrypt data and corresponding private key is used by c# server to decrypt data encrypted by java client

Java client encryting message with public key as following xml

<rsakeyvalue><modulus>z3iQSLN4e7LEZDkb6QSvHXXmQuMRPOYpP6R18WflUGMUk38xGEwd6ieO5DqpqdLnQ+GafFuKOnnPv9wXSuGX0xb9mTgaKQJX0LJSFKHc8G7A511UYn2wuOBDnRSOB09GcPa4T/CYjdP1MRxMecwL2eZ7BJWHU94TtBxfe0soQf0=</modulus><exponent>AQAB</exponent>


public class RSATest {



public static void Encrypt() throws Exception {

Cipher rsa = Cipher.getInstance("RSA");

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

byte[] modulusBytes = new BASE64Decoder().decodeBuffer("z3iQSLN4e7LEZDkb6QSvHXXmQuMRPOYpP6R18WflUGMUk38xGEwd6ieO5DqpqdLnQ+GafFuKOnnPv9wXSuGX0xb9mTgaKQJX0LJSFKHc8G7A511UYn2wuOBDnRSOB09GcPa4T/CYjdP1MRxMecwL2eZ7BJWHU94TtBxfe0soQf0=");
byte[] exponentBytes = new BASE64Decoder().decodeBuffer("AQAB");

BigInteger modulus = new BigInteger(1, modulusBytes);
BigInteger exponent = new BigInteger(1, exponentBytes);

RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
PublicKey publicKey = keyFactory.generatePublic(keySpec);

rsa.init(Cipher.ENCRYPT_MODE, publicKey);

byte[] encryptedData = rsa.doFinal("password would workahdsasdfiosfadioasdio".getBytes(new US_ASCII()));

String encryptedString = HexConversions.bytesToHex(encryptedData);
System.out.println(encryptedString);
System.out.println(encryptedString.length());

}

public static void main(String []arg) throws Exception {
Encrypt();
}
}

C# Code to decrypt what was encrypted by java client

using System;
using System.Globalization;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace ConsoleApplication1
{
internal class Program
{
private static RSACryptoServiceProvider rsa;
private static string publicKey;
private static string privateKey;

private static void Main(string[] args)
{
GenerateKeys();
string encryptedPassword = EncryptData();

string decryptedPassword =

DecryptData("57851E00296519064288CF5B014FE478B703D046648D8F3DEFE715C424670E63F6EFBDC2D7964E17C7C7618EF206F46871536184663725F2EB16FBE9E76872D1

2977F50EE2BDC2C6289A4FBC3C4DA48ED85F12734F97170BA1670BAF610FBA5DB407B18A98CECAA9EFEC4D48C5FA13B4AB771029239B501BB5CCC6235E4041F6");

Console.WriteLine(decryptedPassword);
Console.ReadKey();
}


private static string DecryptData(string encryptedPassword)
{
RSACryptoServiceProvider clientRSAProvider = new RSACryptoServiceProvider();
clientRSAProvider.FromXmlString(File.ReadAllText("D:\\wsgCertificates\\privateKey.txt"));
byte[] bytes = new byte[encryptedPassword.Length/2];
for (int i = 0; i < encryptedPassword.Length; i += 2)
{
bytes[i/2] = byte.Parse(encryptedPassword.Substring(i, 2), NumberStyles.HexNumber);
}

byte[] decrypt = clientRSAProvider.Decrypt(bytes, false);
return Encoding.ASCII.GetString(decrypt);
}

public static string EncryptData()
{
RSACryptoServiceProvider clientRSAProvider = new RSACryptoServiceProvider();
clientRSAProvider.FromXmlString(publicKey);

byte[] encrypt = clientRSAProvider.Encrypt(Encoding.ASCII.GetBytes("hi tesint aaaaaaaaassword"), false);
StringBuilder stringBuilder = new StringBuilder();
foreach (var byteValue in encrypt)
{
stringBuilder.Append(byteValue.ToString("X2"));
}
return stringBuilder.ToString();
}

public static string EncryptDataDSA()
{
DSACryptoServiceProvider clientRSAProvider = new DSACryptoServiceProvider();
clientRSAProvider.FromXmlString(publicKey);

byte[] encrypt = clientRSAProvider.SignData(Encoding.ASCII.GetBytes("hi tesint aaaaaaaaassword"));
StringBuilder stringBuilder = new StringBuilder();
foreach (var byteValue in encrypt)
{
stringBuilder.Append(byteValue.ToString("X2"));
}
return stringBuilder.ToString();
}

public static void GenerateKeys()
{
RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider();
publicKey = rsaCryptoServiceProvider.ToXmlString(false);
privateKey = rsaCryptoServiceProvider.ToXmlString(true);
WriteKey(publicKey, "D:\\wsgCertificates\\publicKey.txt");
WriteKey(privateKey, "D:\\wsgCertificates\\privateKey.txt");
}



private static void WriteKey(string key, string keyFileName)
{
StreamWriter writer = new StreamWriter(keyFileName);
writer.WriteLine(key);
writer.Close();
}
}
}