Entity with simple key referencing another with composite key

Asked

Viewed 412 times

1

I am using Fluent Nhibernate for mapping my classes, and I have the following situation:

User class

public class UsuarioMap : ClassMap<Usuario>
{
    public UsuarioMap()
    {
        Table("USUARIOS");
        Id(x => x.ID, "USUARIO_ID").GeneratedBy.Increment();
        //Comentado para evitar código desnecessário

        References(x => x.Proprietario).Columns("PROPRIETARIO_ID", "SERVIDOR_ID");
    }
}

Proprietary Class Map:

public class ProprietarioMap : ClassMap<Proprietario>
{
    public ProprietarioMap()
    {
        ReadOnly();

        Table("PROPRIETARIOS");
        CompositeId().
            KeyProperty(x => x.ID, "PROPRIETARIO_ID").
            KeyProperty(x => x.ServidorId, "SERVIDOR_ID");

        Id(x => x.ID, "PROPRIETARIO_ID").GeneratedBy.Assigned();

        //Comentado para evitar código desnecessário
    }
}

When trying to save a Usuario, I get a ArgumentOutOfRangeException. The object I try to save is as follows:

var usuario = new Usuario
{
    Proprietario = new Proprietario { ID = 1497196, ServidorId = 2 }
    // Comentado para evitar código desnecessário
};

It’s interesting that if I create a property ProprietarioID in class Usuario and map it, the object is saved smoothly.

What am I doing wrong? Mapping one compound entity into another simple is correct?

  • It is necessary to Id(x => x.ID, "PROPRIETARIO_ID").GeneratedBy.Assigned(); in the mapping of Proprietario? 'Cause I checked with a similar scenario that I have here on my project, and it’s very much like yours.

  • Hi Fernando, thanks for the reply. I tried to remove Generatedby.Assigned, but the error persisted...

  • In the table of Proprietario has a record with the identifiers new Proprietario { ID = 1497196, ServidorId = 2 }, previously registered? Not that it is this, but it is a possibility.

  • Yes, the registration already exists in Proprietary

  • You could get more details from ArgumentOutOfRangeException, type capture the entire error stack. To try to find the origin of the Exception, since Argued tofrangeexception is a Exception triggered by an invalid and non-null argument.

  • Then follow the Stack Trace generated: http://pastebin.com/jAjsR2C5

  • I changed the mapping of Proprietario for the following form: References(x => x.Proprietario).Columns("PROPRIETARIO_ID", "SERVIDOR_ID").Not.Update().Not.Insert(); The error now consists of ORA-01400: não é possível inserir NULL em ("BANCO"."USUARIOS"."PROPRIETARIO_ID")

  • Is it possible to get the SQL generated by Nhibernate before running effectively in the database? To show the SQL add the .ShowSql() in your settings, it is something similar to this if you are using Oracle: OracleClientConfiguration.Oracle10.ConnectionString(ConnectionString).ShowSql();

  • Follow the SQL, which is really not passing the PROPRIETARIO_ID: http://pastebin.com/0bR7nNAK For the mapping scenario without .Not.Update().Not.Insert(), nor is SQL generated (I am checking by Nhibernate Profiler)

  • I solved the issue by mapping a private field called proprietarioID, and pointing the map to it: Map(x => x.ProprietarioID).Column("PROPRIETARIO_ID").Access.CamelCaseField(Prefix.None); In the User class, I changed the constructor to receive a parameter of the Proprietary type, with at least ID and Servorid, and the Proprietary property now only has get, where I return the database object. Anyway, thank you @Fernando for the help!

Show 5 more comments

1 answer

1

I solved the issue by mapping a private field called proprietarioID, and pointing the map to it:

Map(x => x.ProprietarioID).Column("PROPRIETARIO_ID").Access.CamelCaseField(Prefix.None);`

In class Usuario, I changed the constructor to receive a parameter of type Proprietario, with at least ID and ServidorID, and the property Proprietario now only has get, where return the object of the bank. In any case, many thanks @Fernando for the help!

 public virtual Proprietario Proprietario
 {
     get
     {
         if (proprietario != null)
             return proprietario;

         if (proprietarioID == 0 || ServidorID == 0) return null;
         proprietario = new Repository<Proprietario>().Get(proprietarioID, SrvUn);
         return proprietario;
     }
 }

 public Usuario() : this(null)
 {

 }

 public Usuario(Proprietario proprietario)
 {
     if (proprietario == null) return;

     proprietarioID = proprietario.ID;
     this.proprietario = proprietario;
 }
  • If you solved the problem, you can mark your answer as accepted.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.