ConstraintViolationException with Hibernate Kotlin - spring

I have a SQL table with a UniqueConstraint with the name unique_entry. This unique constraint essentially checks if the combination of two specific fields (let's say foo and bar) are unique. While using Hibernate, if I violate this specific constraint, when I catch the exception, it should be an instance of ConstraintViolationException right? If yes, should this if statement be true?
catch (e: ConstraintViolationException) {
if (e.constraintName?.equals("unique_entry", ignoreCase = true) == true) {
.....
}
Basically, I want to handle the exception in a specific way if that unique constraint is triggered. Am I doing it the right way?

Related

In Spring-Hibernate project how can I use getByKey(PK key) and saveOrUpdate(Obejct object) on the same table in a same row in a single transaction

Here in the following code when I invoke discoverAsync method by passing a node which is already in table, it should check that node id is exist in a table and update the other field in that row. But actually it is not happening, hiberbate is just selecting but not updating.
What my point of view is that we can not retrieve and update the same row at a same time in a same transaction. Please correct me if wrong.
Here is the code:
public Node discoverAsync(Node node) throws Exception {
if(isNodeIdEqual(node))
super.saveOrUpdate(node);
else
// TODO Raise Exception in case no node is available for discovery.
return node;
}
public boolean isNodeIdEqual(Node node){
String id = node.getId();
String retrievedId = getByKey(id).getId();
return id.equals(retrievedId);
}
You don't need to check using your method isNodeIdEqual. Hibernate's saveOrUpdate will do that for you. If the record with a particular key is not found, it will save, if it found it will update by the key

How can I make LINQ Lambda expressions fail gracefully like XPath?

More a general question, but how can I write LINQ Lambda expressions such that they will return a default string or simply an empty string if the LINQ expression fails or returns nothing. In XSLT XPath if a match fails then one just got nothing, and the application did not crash whereas in LINQ one seems to get exceptions.
I use First() and have tried FirstOrDefault().
So example queries may be:
Customers.First(c=>c.id==CustId).Tasks.ToList();
or
Customers.Where(c=>c.id==CustId).ToList();
or
Model.myCustomers.Where(c=>c.id==CustId);
etc.
Whatever the query, if it returns no records or null, then is there a general approach to ensure the query fails gracefully?
Thanks.
There isn't anything elegant built into C# for propagating nulls when you access properties. You could create your own extension methods:
public static class Extensions
{
public static TValue SafeGet<TObject, TValue>(
this TObject obj,
Func<TObject, TValue> propertyAccessor)
{
return obj == null ? default(TValue) : propertyAccessor(obj);
}
public static IEnumerable<T> OrEmpty<T>(this IEnumerable<T> collection)
{
return collection ?? Enumerable.Empty<T>();
}
}
Used like this:
Customers.FirstOrDefault(c => c.id==CustId).SafeGet(c => c.Tasks).OrEmpty().ToList();
Customers.First(c=>c.id==CustId) will crash if there is no matching record.
There are few ways you can try to find it, if you use FirstOrDefault that'll return NULL if no match is found and you can check for NULL.
Or, you can use the .Any syntax which checks if you have any record and returns boolean.
The only query I would expect to throw an exception would be the first one (assuming that Customers is a valid collection and not null itself):
Customers.First(c=>c.id==CustId).Tasks.ToList();
This will throw an exception if there is no customer with an id of CustId (you have some casing issues with your property and variable names).
If you don't wish to throw an exception on no match, then use FirstOrDefault as you mention, and do a null check, e.g:
var customer = Customers.FirstOrDefault(c => c.id == CustId);
if (customer == null)
{
// deal with no match
return;
}
var taskList = customer.Tasks.ToList();

Imported unique constraints doesn't get validated

I have a Spring Security User class which has a unique constraint for username and email. In a Command class I imported all constraints from this class with "importFrom User". All constraints work as expected EXCEPT the unique ones.
However when saving the User the unique constraints get validated and errors are shown. But it would be nice if they get validated BEFORE saving like all other constraints.
UPDATE
I added this to the controller:
user.errors.fieldErrors.each {
command.errors.rejectValue(it.getField(), it.getCode())
}
Seems like a dirty workaround, but it works.
Good question #Chris, and your solution is best since the goal of sharing constraints between domain classes and command objects is to avoid duplicating validation logic.
I'll just add that to avoid duplicating field errors and to handle nested field paths in domain objects, something like the following might be necessary.
def save(EntityCreateCommand cmd) {
def entity = new Entity(cmd.properties)
def someAssociation = new Something(cmd.properties)
entity.someAssociation = someAssociation
entity.validate()
entity.errors.fieldErrors.each {
def fieldName = it.field.split("\\.").last()
def flattenedCodes = cmd.errors.getFieldErrors(fieldName).codes.flatten()
if(cmd.hasProperty(fieldName) && (!flattenedCodes.contains(it.code))) {
cmd.errors.rejectValue(fieldName,
"entityCreateCommand.${fieldName}.${it.code}")
}
}
if(cmd.errors.hasErrors()) {
error handling stuff...
} else {
business stuff...
}
}
I had problems with unique constraint before, so I made a custom validator in my command object to test and see if it's unique:
Command Object:
class wateverCommand{
....
String username
static constraints = {
username validator:{value, command ->
if(value){
if(User.findByUsername(value){
return 'wateverCommand.username.unique'
}
}
}
}
}
within your messages.properties add a custom error message:
wateverCommand.username.unique The username is taken, please pick a new username
I agree the unique constraint doesn't always seem to import properly. Since I like to avoid clutter in the constraint body I like the one liner approach:
validator: {value, command -> (User.findByUsername(value) ? false : true ) }
Then in your message.properties it would be:
accountCommand.username.validator.error=That username already exists

How i can force the entity framework to raise a unique exception if the Unique key constraint has been violated on thr sql server database

I have a table named countries and i define the country_name field to be unique by creating a “Index/Key” of type “Unique Key” on sql servwer 2008 r2.
But currently if the user insert a country_name value that already exists on my asp.net mvc3 application, then an exception of type “System.Data.Entity.Infrastructure.DbUpdateException” will be raised , which is very general.
So is there a way to define a specific exception in case the unique constraint has been violated ??? rather than just raising the general “System.Data.Entity.Infrastructure.DbUpdateException” exception?
BR
Most likely, thought I can't test it at the moment, the inner exception of DbUpdateException is probably an exception about a duplicate or foreign key constraint. More importantly, you have an opportunity to not throw any exceptions by checking to see if a country already exists. Two ways I can think of are to; check and see if the country already exists by doing a simple select, and if it doesn't, doing an insert/add or write a stored procedure that and do a select/insert or merge and return any value(s) you want back.
Update
(this is example code to demonstrate the logic flow of events and not good programming practice, specially by catching all excepts)
Exception Logic
public AddCountry(string countryTitle)
{
using (var db = new DbContext(_connectionString)
{
try
{
// Linq to (SQL/EF)-ish code
Country country = new Country();
country.ID = Guid.NewGuid();
country.Title = countryTitle;
db.Countrys.Add(country);
db.SubmitChanges(); // <--- at this point a country could already exist
}
catch (DbUpdateException ex)
{
// <--- at this point a country could be delete by another user
throw Exception("Country with that name already exists");
}
}
}
Non-Exception Logic
public AddCountry(string countryTitle)
{
using (var db = new DbContext(_connectionString)
{
using (TransactionScope transaction = new TransactionScope())
{
try
{
Country country = db.Countries
.FirstOrDefault(x => x.Title = countryTitle);
if (country == null)
{
country = new Country();
country.ID = Guid.NewGuid();
country.Title = countryTitle;
db.Countrys.Add(country);
db.SubmitChanges(); // <--- at this point a country
// shouldn't exist due to the transaction
// although someone with more expertise
// on transactions with entity framework
// would show how to use transactions properly
}
}
catch (<someTimeOfTransactionException> ex)
{
// <--- at this point a country with the same name
// should not exist due to the transaction
// this should really only be a deadlock exception
// or an exception outside the scope of the question
// (like connection to sql lost, etc)
throw Exception("Deadlock exception, cannot create country.");
}
}
}
}
Most likely the TransactionScope(Transaction transactionToUse) Constructor would be needed and configured properly. Probably with an Transactions.IsolationLevel set to Serializable
I would also recommend reading Entity Framework transaction.

Linq throwing exception when Null is returned to a string - attribute on a class?

I have a Linq query which I am selecting into a string, of course a string can contain null!
So is there a way I can throw an exception within my Linq query, if I detect a null?
Can I decorate my class with an attribute that won't let it allow null?
I would like to wrap my Linq query in a try catch, and as soon as a null is detected then it would enter the catch, and I can handle it.
Edit
Here's my Linq query, it's quite simple currently. I am going to extend it, but this shows the basic shape:
var localText = from t in items select new Items { item = t.name }
Basically item is set to t.name, t.name is a string so it could be empty / null is this perfectly legal as its a string and strings can hold NULL.
So if it returns NULL then I need to throw an exception. Actually it would be handy to be able to throw an exception is NULL or empty.
I seemed to remember some kind of Attributes that can be set on top of properties that says "Don't accept null" etc.?
Edit
I think I found it: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.requiredattribute.aspx
This doesn't allow null or strings so I presume it throws an exception, I have used this with MVC but I am not sure if I can use it with a standard class.
As a string being null isn't particularly exceptional, you could do something like:
var items = myStrings.Where(s => !string.IsNullOrEmpty(s)).Select(s => new Item(s));
UPDATE
If you are reading this data from an XML file, then you should look into LINQ to XML, and also use XSD to validate the XML file rather than throwing exceptions on elements or attributes that don't contain strings.
You could try intentionally generating a NullReferenceException:
try
{
//Doesn't change the output, but throws if that string is null.
myStrings.Select(s=>s.ToString());
}
catch(NullReferenceException ex)
{
...
}
You could also create an extension method you could tack on to a String that would throw if null:
public static void ThrowIfNull(this string s, Exception ex)
{
if(s == null) throw ex;
}
...
myString.ThrowIfNull(new NullReferenceException());
Why do you want to throw an exception in this case? This sounds like throwing the baby out with the bath water for something that should not happen in the first place.
If you just want to detect that there are null/empty items:
int nullCount= items.Count( x=> string.IsNullOrEmpty(x.name));
If you want to filter them out:
var localText = from t in items where !string.IsNullOrEmpty(t.name) select new Items { item = t.name };

Resources