I am trying to determine what the Error Code is from an exception that is thrown when interacting with a domain object in Grails.
I have a database that has some field validations, and one of the validations is that a specific column must be unique. According to the docs it will give an Error Code of className.propertyName.unique(http://grails.org/doc/latest/ref/Constraints/unique.html). When I wrap my controller in a try catch block like. I can catch all kinds of validation exceptions this:
catch (grails.validation.ValidationException e) {
exception handling code here
}
How do I access the Error Code? I would like to do something like If the Error Code = className1.propertyName2.unique, then respond propertyName2 is not unique.
I do have "failOnError: true" set as a parameter when I do my save operation.
Thanks!
The Error Code is burried deep within the object. It will be one of the items in the list that is returned by calling the following code, where 'e' is the exception object.
e.getErrors().getFieldError()
You can also get just the code ("unique" in this case) from the exception by calling the following:
e.getErrors().getFieldError().getCode()
Related
In a CrudPanel I have the need to update some items (not through the CRUD dialog). Something like this:
#Transactional
...
instance.setSomeAttribute(newValue);
return savedInstance = instanceRepository.save(instance);
Calling refreshAll on the dataProvider after the update produces the warning Got an RPC for non-existent node: xxxx. Also I guess it is a little expensive to refresh all items if just one changed.
Calling the specific refresh item, on the other side, refreshItem(instance), gives Object of class [...MenuItem] with identifier [xxxx]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
I also tried to pass newInstance to refreshItem, same result.
Can somebody indicate how to proceed?
Check equals and hashCode that they don't contain fields that may have changed when you call refreshItem.
I want to filter the Error Messages that gets populated as part of data annotation modelstate validation failure. As in if an array of objects comes as a part of class, and the validation fails for more than one object, I do not want the same message to be added again and again. Instead, I want to find the distinct error messages
string ValidationFailure= string.Join(";", actionContext.ModelState.Values.Distinct().Select(x.ErrorMessage));
But not able to get the required output.
It looks like your attempt is close, but you’re using Distinct on something that’s already unique (Values). Instead, try the following variation:
string ValidationFailure = string.Join(";", actionContext.ModelState.Values.Select(x => x.ErrorMessage).Distinct());
This ensures that you get a distinct list of ErrorMessages.
If I execute this code in the Grails console:
def p = new Post(title: "T");
p.save(flush: true); // or p.save();
Post.count();
GORM is not throwing any exceptions, but the data is not saved in my DB. What am I doing wrong?
It's likely you have a constraint violation. Add failOnError: true to your save method parameters. Then you'll get an exception when your save fails. (Alternatively you can check the return value from save, and if it's false print out p.errors.allErrors().)
Validation and saving are done together. If you are validating user-submitted data that's been bound to some domain object, then in order to check for the save failing due to invalid input the idiomatic thing to do is check the return value of save; failing on account of invalid input is not exceptional behavior. If you just want to save the contents of the object and want an exception thrown if there's a problem, use failOnError.
For more on the rationale on why they designed GORM so that you need to do this see this article.
Likely some constraint on Post is being violated and thus the object is not being saved. Note that the default behavior of GORM is not to throw on a failed save. You need to either call it like
p.save(flush: true, failOnError: true);
Or change the behavior globally by adding
grails.gorm.failOnError=true
to your Config.groovy
While updating with the help of LINQ to SQL using Entity Framework, an exception is thrown.
System.Data.UpdateException: Unable to update the EntitySet 't_emp' because it has
a DefiningQuery and no <UpdateFunction> element exists in the
<ModificationFunctionMapping>
The code for update is :
public void Updateall()
{
try
{
var tb = (from p in _te.t_emp
where p.id == "1"
select p).FirstOrDefault();
tb.ename = "jack";
_te.ApplyPropertyChanges(tb.EntityKey.EntitySetName, tb);
_te.SaveChanges(true);
}
catch(Exception e)
{
}
}
Why am I getting this error?
The problem was in the table structure. To avoid the error we have to make one primary key in the table. After that, update the edmx. The problem will be fixed
Three things:
Don't catch exceptions you can't handle. You're catching every exception possible, and then doing nothing with it (except swallowing it). That's a Bad Thing™ Do you really want to silently do nothing if anything goes wrong? That leads to corrupted state that's hard to debug. Not good.
Linq to SQL is an ORM, as is Entity Framework. You may be using LINQ to update the objects, but you're not using Linq to SQL, you're using Entity Framework (Linq to Entities).
Have you tried the solution outlined here? The exception you posted is somewhat cut off, so I can't be sure it's exactly the same (please update your post if it isn't), and if it is the same, can you comment on whether or not the following works for you?
"[..] Entity Framework doesn't know whether a given view is updatable
or not, so it adds the <DefiningQuery> element in order to safeguard
against having the framework attempt to generate queries against a
non-updatable view.
If your view is updatable you can simply remove the <DefiningQuery>
element from the EntitySet definition for your view inside of the
StorageModel section of your .edmx, and the normal update processing
will work as with any other table.
If your view is not updatable, you will have to provide the update
logic yourself through a "Modification Function Mapping". The
Modification Function Mapping calls a function defined in the
StorageModel section of your .edmx. That Function may contain the
name and arguments to a stored procedure in your database, or you can
use a "defining command" in order to write the insert, update, or
delete statement directly in the function definition within the
StorageModel section of your .edmx." (Emphasis mine, post formatted for clarity and for Stack Overflow)
(Source: "Mike" on MSDN)
But You can Set primary Key in Model if use MVC Asp.net
Just Open model.edmx in your table ,go to your field property and set Entity Key = True
i'm trying to create some domain objects from xml.
class A {
String name
}
class B {
A a
int something
}
i first created an instance of A,and flushed. when creating B, first map the available attributes.
def b = new B(xml.attributes())
this would map 'something' correctly, but not the object type A. So, I retrieve the instance of A and add like
b.a = A.findByA("id of a")
I could see the object b is constructed (both fields filled in) in the debugger, but it doesn't persist on save(flush:true).
What is wrong in the above assignemt, or should use the id instead (b.a.id = ..)
How can I see what is going wrong in the log file? which trace needs to be enabled. I enabled there in config file
trace 'org.hibernate.SQL', 'org.hibernate.type' (which gives the sql trace for insert, select etc. But not for the above scenario, may be because it doesn't reach to hibernate).
Any pointer, highly appreciated.. thanks.
I would wager to guess that your save() is failing validation. You can add save(failOnError:true) to throw an exception when the validation fails, or add the following code to print each of the errors:
b.errors.allErrors.each {
println it
}
With the debugging tip from Rich, I could narrow down the problem... had to rename the attribute to prevent auto mapping. See a similar issue, and response at http://grails.1312388.n4.nabble.com/domain-controller-and-Failed-to-convert-property-value-of-type-problem-td1357947.html
To create association you must pass an object of A
new B(a:A.get(id))
or
B b = new B()
b.a = A.get(id)
Where id must be Integer or Long
Either I miss some context but class A doesn't have method findByA. There is no such A attribute for class A. Suggest you to use method get for strict findings.