Monday, January 23, 2012

NHibernate proxy of incorrect type exception: "PropertyAccessException Invalid Cast (check your mapping for property type mismatches)"

Are you facing this exception?

NHibernate.PropertyAccessException : Invalid Cast (check your mapping for property type mismatches); setter of MyEntity ----> System.InvalidCastException : Unable to cast object of type 'MyOtherEntityProxy' to type 'AnotherEntity'.

Looking on google, I saw that other programmers have this type of problem.

This article can help you if you are using Ninject and uNhAddIns.NinjectAdapters for entity injection in NHibernate.

If you are using the "NinjectAdapter" assembly, you need to bind the IProxyFactory interface to a class, for example to the default provided with NHibernate, DefaultProxyFactory, if is good for you.
My problem was the definition of this bind in a Ninject kernel module, copied from somewhere on the net or from a book, I can't remember.
   Bind<NHibernate.Proxy.IProxyFactory>()
      .To<NHibernate.Proxy.DefaultProxyFactory>()
      .InSingletonScope(); // <= here the problem


Declaring this bind in singleton scope is not good because the instance will be shared between NHibernate entities metadata classes: so you will get always the first ProxyFactory instance created and you will receive an error like the one above at runtime when you need a proxy classes of a type different from the first one created.

Was really a pain and take a lot of time to find out the problem as you can image, and the solution is to declare the bind InTransientScope(), of course.

   Bind<NHibernate.Proxy.IProxyFactory>()
      .To<NHibernate.Proxy.DefaultProxyFactory>()
      .InTransientScope(); // <= problem fixed

Here the documentation about the object scopes in Ninject.

Doing a similar mistake, you could have the same problem with another dependency injection library like Sprint.Net or CastleWindsor, of course.

Hope it helps :)

Wednesday, January 18, 2012

Antivirus real time gratis per Windows: ClamWin + ClamSentinel

L'utilizzo dell'antivirus in questi ultimi anni è diventato uno strumento obbligatorio, sopratutto in ambiente Windows.
Perché spendere dei soldi per acquistare un antivirus quando sulla rete possiamo trovare dei software interamente gratis e di buona qualità!? La soluzione che andiamo a descrivere è l'unione di due programmi open source: ClamWin e ClamSentinel. Questi due programmi sono progetti di software libero ed entrambi fanno capo al progetto Clam AntiVirus.

- ClamWin fornisce un'interfaccia grafica per il motore antivirus ClamAV ma non supporta la scansione del sistema in tempo reale. Per colmare questa lacuna andremo ad utilizzare un altro software.
Disponibile al seguente link: http://sourceforge.net/projects/clamwin/

- ClamSentinel è un programma che monitora costantemente ogni modifica ai propri file e ne controlla il contenuto alla ricerca di virus usando ClamWin.
Disponibile al seguente link: http://sourceforge.net/projects/clamsentinel/

Qualcuno potrebbe obiettare che esistano già antivirus commerciali in versione gratuita.
Sì è vero, ma Clam Antivirus non è una seconda scelta né tanto meno una versione ridotta: è il miglior software disponibile in maniera totalmente libera, gratuita e senza pubblicità.

Wednesday, January 11, 2012

Efficient and scalable select of a random record in PostgreSQL


This is a code snippet for the select of a random record in a efficient and scalable way when using PostgreSQL:

   SELECT * FROM table_name
   LIMIT 1
   OFFSET (SELECT Random() * Count(*) FROM table_name);

According with the manual, the Random() function return a random value in the range 0.0 <= x < 1.0 .
So the effect of the expression (Random() * Count(*)) is to return a value between 0 and Count(*): we can use this value as offset to skip a random values of records.

This work in PostgreSQL 8.* and 9.*.

This solution required two queries, but if you have many records, is more efficient than this other one :

   SELECT * FROM table_name
   ORDER BY Random()
   LIMIT 1;

In this solution the Random() function is called for each row, so with many records it could be inefficient in term of execution time and memory usage.

Friday, January 6, 2012

Ubuntu GNU/Linux: configurare Samba per condividere cartelle

Esempio di condivisione cartelle con Samba su Ubuntu Linux: 

Cartelle condivise:
backup (accessibile da tutti gli utenti)
db (accessibile da tutti gli utenti)
scambio (accessibile da tutti gli utenti)
utente.1 (accessibile solo da utente1)
utente.2 (accessibile solo da utente2)

Creazione utenti:
sudo useradd -c “admin condiviso” -m -g users -p 123456789 super
nome completo = admin condiviso
gruppo di appartenenza = users
password = 123456789
username = super
sudo smbpasswd -a super

sudo useradd -c “utente uno” -m -g users -p 1234567890 utente1
nome completo = utente uno
gruppo di appartenenza = users
password = 1234567890
username = utente1
sudo smbpasswd -a utente1

sudo useradd -c “utente due” -m -g users -p 12345678 utente2
nome completo = utente due
gruppo di appartenenza = users
password = 12345678
username = utente2
sudo smbpasswd -a utente2

Creazione cartelle:
sudo mkdir /dati
sudo mkdir -m 777 /dati/backup
sudo mkdir -m 777 /dati/db
sudo mkdir /dati/utenti
sudo mkdir -m 777 /dati/utenti/utente.1
sudo mkdir -m 777 /dati/utenti/utente.2
sudo mkdir -m 777 /dati/utenti/scambio

Editare il file /etc/samba/smb.conf:
sudo vi /etc/samba/smb.conf
[global]
workgroup = workgroup
netbios name = serer
server string  = server_dati
security = user
encrypt passwords = yes
browsable = yes

[backup]
path = /dati/backup
comment = cartella_backup
read only = no
valid users = super utente1 utente2

[db]
path = /dati/db
comment = cartella_db
read only = no
valid users = super utente1 utente2

[scambio]
path = /dati/utenti/scambio
comment = cartella_scambio
read only = no
valid users = super utente1 utente2

[utente.1]
path = /dati/utenti/utente.1
comment = cartella_utente1
read only = no
valid users = super utente1

[utente.2]
path = /dati/utenti/utente.2
comment = cartella_utente2
read only = no
valid users = super utente2

Assicurati che tutto sia OK digitando:
sudo testparm

Riavviare servizio samba:
sudo /etc/init.d/smbd restart 

Wednesday, January 4, 2012

NHibernate mapping by code a sequence generator

How to map an identifier when you want to use a sequence generator, like the one used by PosrgreSQL ?
Here is an example in the loquacious way using the ClassMapping<T> base class, and, of course, the MapperModel:

   public sealed class MyEntityMap : ClassMapping<MyEntity>
   {
      public MyEntityMap ()
      {
         Table("my_table");
         Id(x => x.Id,
            a =>
            {
               a.Column("my_id");
               a.Generator(Generators.Sequence, g => g.Params(new
               {
                  sequence = "my_sequence_generator"
               }));
            });
      }
   }

Happy mapping ^^