Avaliação do Tópico:
  • 0 votos - 0 Média
  • 1
  • 2
  • 3
  • 4
  • 5
Erro em campo NotNull
#1
Boa tarde Pessoal,

estou quebrando a cabeça no segunte problema

No banco sqlserver a coluna "Descricao" está como not null.

se eu fizer um insert via management studio 
insert INSERT INTO MESA (DESCRICAO) VALUES ('') - ok

via 
oMesas := TContainerObjectSet<TMesa>.Create(iBDConexao, -1);

Mesa.descricao := '';
oMesas.Insert(Mesa); -ok

porem ao recarregar o clientdataset dá a mensagem "Field value required" e dá access violation e fecha o app.

resposta obvia: "o campo é obrigatorio e estou inserindo vazio ("nao estou mandando null")"

porem ele deixa gravar tanto no sql quanto no container, o problema é ao carregar, não deveria dar essa mensagem visto que o campo não está como null no registro e sim com 'vazio'.

    [Restrictions([NotNull])]
    [Column('DESCRICAO', ftString, 30)]
    [Dictionary('DESCRICAO', 'Descrição da Mesa', '', '', '', taLeftJustify)]
    property descricao: String read FDESCRICAO write FDESCRICAO;


Origens do Problema:
procedure TSessionDataSet<M>.OpenSQL(const ASQL: string);

onde alimenta os fields no cds:
procedure TBindDataSet.SetInternalInitFieldDefsObjectClass(ADataSet: TDataSet; AObject: TObject);

if LColumn.IsNotNull then
      ADataSet.FieldByName(LColumn.ColumnName).Required := True;

se alguem tiver uma solução e puder ajudar, estou tentando aqui mas se alguem conseguir achar algo antes.

obrigado
Responder
#2
(17-09-2018, 08:54 AM)samuca.ti@hotmail.com Escreveu: Boa tarde Pessoal,

estou quebrando a cabeça no segunte problema

No banco sqlserver a coluna "Descricao" está como not null.

se eu fizer um insert via management studio 
insert INSERT INTO MESA (DESCRICAO) VALUES ('') - ok

via 
oMesas := TContainerObjectSet<TMesa>.Create(iBDConexao, -1);

Mesa.descricao := '';
oMesas.Insert(Mesa); -ok

porem ao recarregar o clientdataset dá a mensagem "Field value required" e dá access violation e fecha o app.

resposta obvia: "o campo é obrigatorio e estou inserindo vazio ("nao estou mandando null")"

porem ele deixa gravar tanto no sql quanto no container, o problema é ao carregar, não deveria dar essa mensagem visto que o campo não está como null no registro e sim com 'vazio'.

    [Restrictions([NotNull])]
    [Column('DESCRICAO', ftString, 30)]
    [Dictionary('DESCRICAO', 'Descrição da Mesa', '', '', '', taLeftJustify)]
    property descricao: String read FDESCRICAO write FDESCRICAO;


Origens do Problema:
procedure TSessionDataSet<M>.OpenSQL(const ASQL: string);

onde alimenta os fields no cds:
procedure TBindDataSet.SetInternalInitFieldDefsObjectClass(ADataSet: TDataSet; AObject: TObject);

if LColumn.IsNotNull then
      ADataSet.FieldByName(LColumn.ColumnName).Required := True;

se alguem tiver uma solução e puder ajudar, estou tentando aqui mas se alguem conseguir achar algo antes.

obrigado

Então, existe um NOTNULL na classe e o TField por esse motivo terá Required = TRUE, se add TField no Delphi e no banco tiver NOTNULL verá que será assim tb, então isso não é um problema nem um erro, o que faltou foi entendimento do que quer dizer para o ORMBr esse atributo [Restrictions([NotNull])] e ele cria o TField para o Dataset e faz a mesma coisa que o Delphi faz.

Então como resolver ? Não tem como resolver, pois não existe erro nem problema, mas deve fazer o que se programou da forma certa e existem duas formas:

1a No Atributo Dictionary() defina o valor default do TField assim:  [Dictionary('DESCRICAO', 'Descrição da Mesa', '''''', '', '', taLeftJustify)]

2a No evento NewRecord do ClientDataSet atribua o valor CDS.FieldByName('DESCRICAO').AsString := '';

  Isaque Pinheiro
  Fundador do Projeto ORM Brasil
  ORMBr SAC - Assine e faça parte dessa história ajudando o projeto a crescer.

Responder
#3
ok, no meu caso eu preferiria fazer a consistencia no evento:

procedure TObjectSetAdapter<M>.Insert(const AObject: M);

quando eu tiver um tempo vou tentar buscar as propriedades dos objetos e tentar ver o tipo se está marcado como notnull e campo veio '',
e dar uma mensagem de validação, com o objeto (const AObject: M); não consigo pegar se é not null, eu precisaria pegar [Restrictions([NotNull])] para ver

mas de qualquer forma obrigado.
Responder
#4
se alguem puder me dá um help
não estou conseguindo pegar o valor da propriedade DESCRICAO do objeto

procedure TObjectSetAdapter<M>.Insert(const AObject: M);
var
LColumn: TColumnMapping;
LInTransaction: Boolean;
LIsConnected: Boolean;

LColumn1: TColumnMapping;
LColumns: TColumnMappingList;
begin
LColumns := TMappingExplorer.GetInstance.GetMappingColumn(AObject.ClassType);

for LColumn1 in LColumns do
begin
/// Restrictions
if LColumn1.PropertyRtti.IsNullValue(AObject) then
begin
QUERO PEGAR O VALOR DO CAMPO DESCRICAO DA CLASSE PARA FAZER UMA CONSISTENCIA AQUI.
end;
end;

inherited;
/// <summary>
/// Controle de transação externa, controlada pelo desenvolvedor
/// </summary>
///
LInTransaction := FConnection.InTransaction;
LIsConnected := FConnection.IsConnected;
if not LIsConnected then
FConnection.Connect;
try
if not LInTransaction then
FConnection.StartTransaction;
try
FSession.Insert(AObject);
if FSession.ExistSequence then
begin
for LColumn in AObject.GetPrimaryKey do
SetAutoIncValueChilds(AObject, LColumn);
end;
/// <summary>
/// Executa comando insert em cascade
/// </summary>
CascadeActionsExecute(AObject, CascadeInsert);
///
if not LInTransaction then
FConnection.Commit;
except
on E: Exception do
begin
if not LInTransaction then
FConnection.Rollback;
raise Exception.Create(E.Message);
end;
end;
finally
if not LIsConnected then
FConnection.Disconnect;
end;
end;
Responder
#5
(19-09-2018, 04:45 PM)samuca.ti@hotmail.com Escreveu: se alguem puder me dá um help
não estou conseguindo pegar o valor da propriedade DESCRICAO do objeto

procedure TObjectSetAdapter<M>.Insert(const AObject: M);
var
 LColumn: TColumnMapping;
 LInTransaction: Boolean;
 LIsConnected: Boolean;

 LColumn1: TColumnMapping;
 LColumns: TColumnMappingList;
begin
  LColumns := TMappingExplorer.GetInstance.GetMappingColumn(AObject.ClassType);

 for LColumn1 in LColumns do
 begin
  /// Restrictions
   if LColumn1.PropertyRtti.IsNullValue(AObject) then
   begin
      QUERO PEGAR O VALOR DO CAMPO DESCRICAO DA CLASSE PARA FAZER UMA CONSISTENCIA AQUI.
   end;
 end;

 inherited;
 /// <summary>
 /// Controle de transação externa, controlada pelo desenvolvedor
 /// </summary>
 ///
 LInTransaction := FConnection.InTransaction;
 LIsConnected := FConnection.IsConnected;
 if not LIsConnected then
   FConnection.Connect;
 try
   if not LInTransaction then
     FConnection.StartTransaction;
   try
     FSession.Insert(AObject);
     if FSession.ExistSequence then
     begin
       for LColumn in AObject.GetPrimaryKey do
         SetAutoIncValueChilds(AObject, LColumn);
     end;
     /// <summary>
     /// Executa comando insert em cascade
     /// </summary>
     CascadeActionsExecute(AObject, CascadeInsert);
     ///
     if not LInTransaction then
       FConnection.Commit;
   except
     on E: Exception do
     begin
       if not LInTransaction then
         FConnection.Rollback;
       raise Exception.Create(E.Message);
     end;
   end;
 finally
   if not LIsConnected then
     FConnection.Disconnect;
 end;
end;

Você terá que usar RTTI ai para fazer isso que pediu.

Agora é o seguinte, usando DataSet o NOTNULL o proprio Delphi valida isso pelo TField, mas para Objeto isso está começado através dos atributos NotNullConstraint(), ZeroConstraint() na unit ormbr.mapping.rttiutils.pas tem um método RunValidade(), colocando os atributos nas propriedades da classe a validaçao pode ser feito antes de enviar o método Insert() e Update() assim TRttiSingleton.RunValidade(Object.ClassType)

Como disse isso foi iniciado, podemos testar juntos e implementar o que precisar para deixar 100%

  Isaque Pinheiro
  Fundador do Projeto ORM Brasil
  ORMBr SAC - Assine e faça parte dessa história ajudando o projeto a crescer.

Responder
#6
legal, vou ver oque consigo, pois dá forma que está hoje está dando acess violation e fecha o app
Responder
#7
(20-09-2018, 09:13 AM)samuca.ti@hotmail.com Escreveu: legal, vou ver oque consigo, pois dá forma que está hoje está dando acess violation e fecha o app

Assim que der, vou voltar a fazer alguns testes, vai analisando ai, se achar algo me avisa.

  Isaque Pinheiro
  Fundador do Projeto ORM Brasil
  ORMBr SAC - Assine e faça parte dessa história ajudando o projeto a crescer.

Responder
#8
(20-09-2018, 10:22 AM)Isaque Pinheiro Escreveu:
(20-09-2018, 09:13 AM)samuca.ti@hotmail.com Escreveu: legal, vou ver oque consigo, pois dá forma que está hoje está dando acess violation e fecha o app

Assim que der, vou voltar a fazer alguns testes, vai analisando ai, se achar algo me avisa.

ok, estou vendo aqui e o metodo validate olha somente os atributos, não está olhando dentro deles tipo [Restrictions([NotNull])] 
pega somente Restrictions, nao o notnull, mas vou verificar mais um pouco
Responder
#9
alguem conseguiu alguma coisa?, não estou conseguindo validar

function TRttiSingleton.RunValidade(AClass: TClass): Boolean;
var
LColumn: TColumnMapping;
LColumns: TColumnMappingList;
LAttribute: TCustomAttribute;
begin
Result := False;
LColumns := TMappingExplorer.GetInstance.GetMappingColumn(AClass);
for LColumn in LColumns do
begin
/// <summary>
/// Valida se o valor é NULO
/// </summary>

LAttribute := LColumn.PropertyRtti.GetNotNullConstraint;
if LAttribute <> nil then
NotNullConstraint(LAttribute).Validate(LColumn.ColumnName, LColumn.PropertyRtti.GetNullableValue(AClass));
/// <summary>
/// Valida se o valor é menor que ZERO
/// </summary>
LAttribute := LColumn.PropertyRtti.GetZeroConstraint;
if LAttribute <> nil then
ZeroConstraint(LAttribute).Validate(LColumn.ColumnName, LColumn.PropertyRtti.GetNullableValue(AClass));

/// <summary>
/// Valida se o valor é '' vazio
/// </summary>
LAttribute := LColumn.PropertyRtti.GetRestriction;
if LAttribute <> nil then
begin
if NotNull in Restrictions(LAttribute).Restrictions then
begin
NotNullConstraint(LAttribute).Validate(LColumn.ColumnName, LColumn.PropertyRtti.GetNullableValue(AClass));
end;
end;
end;
Result := True;
end;


if NotNull in Restrictions(LAttribute).Restrictions then
begin
NotNullConstraint(LAttribute).Validate(LColumn.ColumnName,
LColumn.PropertyRtti.GetNullableValue(AClass)); //aqui dá access violation
end;
Responder
#10
(26-09-2018, 09:02 AM)samuca.ti@hotmail.com Escreveu: alguem conseguiu alguma coisa?, não estou conseguindo validar

function TRttiSingleton.RunValidade(AClass: TClass): Boolean;
var
  LColumn: TColumnMapping;
  LColumns: TColumnMappingList;
  LAttribute: TCustomAttribute;
begin
  Result := False;
  LColumns := TMappingExplorer.GetInstance.GetMappingColumn(AClass);
  for LColumn in LColumns do
  begin
    /// <summary>
    /// Valida se o valor é NULO
    /// </summary>

     LAttribute := LColumn.PropertyRtti.GetNotNullConstraint;
     if LAttribute <> nil then
        NotNullConstraint(LAttribute).Validate(LColumn.ColumnName, LColumn.PropertyRtti.GetNullableValue(AClass));
    /// <summary>
    /// Valida se o valor é menor que ZERO
    /// </summary>
     LAttribute := LColumn.PropertyRtti.GetZeroConstraint;
     if LAttribute <> nil then
        ZeroConstraint(LAttribute).Validate(LColumn.ColumnName, LColumn.PropertyRtti.GetNullableValue(AClass));

    /// <summary>
    /// Valida se o valor é '' vazio
    /// </summary>
     LAttribute := LColumn.PropertyRtti.GetRestriction;
     if LAttribute <> nil then
     begin
        if NotNull in Restrictions(LAttribute).Restrictions then
        begin
           NotNullConstraint(LAttribute).Validate(LColumn.ColumnName, LColumn.PropertyRtti.GetNullableValue(AClass));
        end;
     end;
  end;
  Result := True;
end;


        if NotNull in Restrictions(LAttribute).Restrictions then
        begin
           NotNullConstraint(LAttribute).Validate(LColumn.ColumnName,
                                                                  LColumn.PropertyRtti.GetNullableValue(AClass)); //aqui dá access violation
        end;

Olá, desculpe a demora, atualizei o fórum de começou um erro ao tentar responder, dava sempre erro, agora corrigi.

Bom como já te passei pelo skype fiz o commit da correção, abraço.

  Isaque Pinheiro
  Fundador do Projeto ORM Brasil
  ORMBr SAC - Assine e faça parte dessa história ajudando o projeto a crescer.

Responder


Possíveis Tópicos Relacionados...
Tópico: Autor Respostas: Visualizações: Última Mensagem
  Erro instanciando TContainerClientDataSet com coluna > 31 caracteres e valor default Odlawso 3 1,271 04-04-2019, 05:37 AM
Última Mensagem: juliomar
  Erro em ormbr.dataset.bind Osiel Gomes 5 2,879 01-03-2019, 08:49 AM
Última Mensagem: Isaque Pinheiro
  Erro de Tycast campo Blob Osiel Gomes 1 1,500 26-11-2017, 10:59 AM
Última Mensagem: juliomar

Saltar Fórum:


usuários a ver este tópico: 1 Visitante(s)