While using Struts2, I am using several annotations to do my validations inside the Model class, in the set() methods, like:
#RequiredStringValidator(message = "Name is required")
#StringLengthFieldValidator(message = "Name must be between 5 and 60 characters",
minLength = "5", maxLength = "60")
public void setName(String name) {
this.name = name;
}
But I would like how to put a validation do avoid Strange characters, like !, ?, #, $ and etc...
Is there any existing validator I should use like a #RestrictChars or maybe is there some way to use the #StringRegexValidator. Or should I write a new one. Any hint or documentation how to do such would be great.
I found it finally:
Just adding the already existent #RegexFieldValidator gave me the Validator I needed:
#RegexFieldValidator(message = "Use only Letters or numbers",
expression = "^[a-zA-Z0-9]+$")
Thanks anyway guys!
Related
This query produces an error No value given for one or more required parameters:
using (var conn = new OleDbConnection("Provider=..."))
{
conn.Open();
var result = conn.Query(
"select code, name from mytable where id = ? order by name",
new { id = 1 });
}
If I change the query string to: ... where id = #id ..., I will get an error: Must declare the scalar variable "#id".
How do I construct the query string and how do I pass the parameter?
The following should work:
var result = conn.Query(
"select code, name from mytable where id = ?id? order by name",
new { id = 1 });
Important: see newer answer
In the current build, the answer to that would be "no", for two reasons:
the code attempts to filter unused parameters - and is currently removing all of them because it can't find anything like #id, :id or ?id in the sql
the code for adding values from types uses an arbitrary (well, ok: alphabetical) order for the parameters (because reflection does not make any guarantees about the order of members), making positional anonymous arguments unstable
The good news is that both of these are fixable
we can make the filtering behaviour conditional
we can detect the category of types that has a constructor that matches all the property names, and use the constructor argument positions to determine the synthetic order of the properties - anonymous types fall into this category
Making those changes to my local clone, the following now passes:
// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = new System.Data.OleDb.OleDbConnection(
Program.OleDbConnectionString))
{
var row = conn.Query("select Id = ?, Age = ?", new DynamicParameters(
new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
) { RemoveUnused = false } ).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo(23);
id.IsEqualTo(12);
}
}
Note that I'm currently using DynamicParameters here to avoid adding even more overloads to Query / Query<T> - because this would need to be added to a considerable number of methods. Adding it to DynamicParameters solves it in one place.
I'm open to feedback before I push this - does that look usable to you?
Edit: with the addition of a funky smellsLikeOleDb (no, not a joke), we can now do this even more directly:
// see https://stackoverflow.com/q/18847510/23354
public void TestOleDbParameters()
{
using (var conn = new System.Data.OleDb.OleDbConnection(
Program.OleDbConnectionString))
{
var row = conn.Query("select Id = ?, Age = ?",
new { foo = 12, bar = 23 } // these names DO NOT MATTER!!!
).Single();
int age = row.Age;
int id = row.Id;
age.IsEqualTo(23);
id.IsEqualTo(12);
}
}
I've trialing use of Dapper within my software product which is using odbc connections (at the moment). However one day I intend to move away from odbc and use a different pattern for supporting different RDBMS products. However, my problem with solution implementation is 2 fold:
I want to write SQL code with parameters that conform to different back-ends, and so I want to be writing named parameters in my SQL now so that I don't have go back and re-do it later.
I don't want to rely on getting the order of my properties in line with my ?. This is bad. So my suggestion is to please add support for Named Parameters for odbc.
In the mean time I have hacked together a solution that allows me to do this with Dapper. Essentially I have a routine that replaces the named parameters with ? and also rebuilds the parameter object making sure the parameters are in the correct order.
However looking at the Dapper code, I can see that I've repeated some of what dapper is doing anyway, effectively it each parameter value is now visited once more than what would be necessary. This becomes more of an issue for bulk updates/inserts.
But at least it seems to work for me o.k...
I borrowed a bit of code from here to form part of my solution...
The ? for parameters was part of the solution for me, but it only works with integers, like ID. It still fails for strings because the parameter length isn't specifed.
OdbcException: ERROR [HY104] [Microsoft][ODBC Microsoft Access Driver]Invalid precision value
System.Data.Odbc. OdbcParameter.Bind(OdbcStatementHandle hstmt,
OdbcCommand command, short ordinal, CNativeBuffer parameterBuffer, bool allowReentrance)
System.Data.Odbc.OdbcParameterCollection.Bind(OdbcCommand command, CMDWrapper cmdWrapper, CNativeBuffer parameterBuffer)
System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader, object[] methodArguments, SQL_API odbcApiMethod)
System.Data.Odbc.OdbcCommand.ExecuteReaderObject(CommandBehavior behavior, string method, bool needReader)
System.Data.Common.DbCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
Dapper.SqlMapper.QueryAsync(IDbConnection cnn, Type effectiveType, CommandDefinition command) in SqlMapper.Async.cs
WebAPI.DataAccess.CustomerRepository.GetByState(string state) in Repository.cs
var result = await conn.QueryAsync(sQuery, new { State = state });
WebAPI.Controllers.CustomerController.GetByState(string state) in CustomerController .cs
return await _customerRepo.GetByState(state);
For Dapper to pass string parameters to ODBC I had to specify the length.
var result = await conn.QueryAsync<Customer>(sQuery, new { State = new DbString { Value = state, IsFixedLength = true, Length = 4} });
at the moment I try to deal with scaffolding in grails. There I have a little problem with the generation-templates where i don't find a solution. I want to configure the generating-algorithm in the domainmodel.
My thought was to define static variables in the model which aren't created in the database and only important for the generation-process.
For example I want to display only some special fields in the show.gsp but i want to display every field in the _form.gsp Or i want to do some gsp-imports but only in seperate gsp.
So i thought that i could define some static variables where the value contains some configuration-parameter i can interpretate in the generation template.
I hope everybody understand what I mean ?
Here is an example:
class Awesome {
Long awesome_level
Long person_name
Boolean itsMe
static String showFields
static transients = ['showFields']
static constraints = {
einrichtungs_type()
type_of_conzept()
anzahl_gruppen()
anzahl_kinder_pro_Gruppe()
offnungszeiten()
showFields(["person_name", "itsMe"])
}
In the Show-View i only want to display the fields in the array "showFields"
...
for (p in props) {
if (p.embedded && p.name in domainClass.showFields) {
def embeddedPropNames = p.component.persistentProperties*.name
def embeddedProps = p.component.properties.findAll { embeddedPropNames.contains(it.name) && !excludedProps.contains(it.name) }
Collections.sort(embeddedProps, comparator.constructors[0].newInstance([p.component] as Object[]))
%><fieldset class="embedded"><legend><g:message code="${domainClass.propertyName}.${p.name}.label" default="${p.naturalName}" /></legend><%
for (ep in p.component.properties) {
renderFieldForProperty(ep, p.component, "${p.name}.")
}
%></fieldset><%
} else {
renderFieldForProperty(p, domainClass)
}
...
I know that the if clause don't work. My problem is, that i am not able to get the value of the field "showFields".
Know my questions:
Is it able to receive the values of a field of a domainclass?
Is it able to execute a methode of a domainclass?
Is there an other way do define configuration-parameters which i can access in the generation-templates?
I hope i was able to display my problem and thank you for some help!
Greetz
V
I found a solution for that problem. First of all I thought it could be possible with the creation of a custom-Constraint. I am still thinking that this is also possible but i found a better /easyer way to add "configurations".
I use the tag attributes, which already exsits. If i understand it right, the attributes parameter i used to add attributes in select-Html-tags. Now i use it for adding some configuration-parameters. Here my solution:
You have to change the "renderEditor.template" that not all the configuration-parameter will add in a HTMl-tag as a attribute. cp.attributes.each { k, v ->
sb << "${k}=\"${v}\" "
} change to cp.attributes?.realAttributes.each { k, v ->
sb << "${k}=\"${v}\" "
}
When you realy want to this attributes-function add into the attributes-parameter the value "realAttributes" (or how you would like to call it)
Change the constraints of the model: (in my example:)
static constraints = { einrichtungs_type(attributes:
[showField:true])
}
Finaly change the generation-template
if(cp.attributes?.showField){
...
I hope these 4 steps help you, if you have nearly the same problems.
Greetz
V
Grails validation fails after interchanging unique attribute values
Hi, I am trying to create an interface where users can create some custom enumeration with translations for different languages. For example the user can create an enumeration "Movie Genre". For this enumeration there might be an enumeration-value "Comedy" for which there might exist one ore more enumeration-value-translations for several languages.
As there must only be one translation for a specific language, I added a unique constraint to the enumeration-value-translation domain class. These are my domain classes right now:
class Enumeration {
String label
List<EnumerationValue> enumerationValues = new ArrayList<EnumerationValue>()
static hasMany = [ enumerationValues: EnumerationValue ]
static constraints = {
label(nullable: false, blank: false)
enumerationValues(nullable: true)
}
}
class EnumerationValue {
String label
List<EnumerationValueTranslation> enumerationValueTranslations = new ArrayList<EnumerationValueTranslation>()
static belongsTo = [ enumeration: Enumeration ]
static hasMany = [ enumerationValueTranslations: EnumerationValueTranslation ]
static constraints = {
label(nullable: false, blank: false, unique: 'enumeration')
enumeration(nullable: false)
enumerationValueTranslations(nullable: false)
}
}
class EnumerationValueTranslation {
String value
Language language
static belongsTo = [ enumerationValue: EnumerationValue ]
static constraints = {
value(nullable: false, blank: false)
language(nullable: true, unique: 'enumerationValue')
enumerationValue(nullable: false)
/* unique constraint as mentioned in description text */
language(unique: 'enumerationValue')
}
}
This works pretty fine so far. My problem occures when I update two enumeration-value-translations of the same enumeration-value in a way that the languages interchange. For example I have an
enumeration-value: "Comedy"
and some translations where the language is "accidentally" mixed up
translations for "Comedy"
language: german, value: "Comedy"
language: english, value "Komödie"
if the user recognizes that he mixed up the language, he might want to swap the languages and save the enumeration again. And this is where my error occures, because after swapping the languages the enumeration-value-translations unique constraint validates to false.
To debug this i simply tryed to print out the error causing translations before and after i processed the params, so:
Enumeration enumeration = Enumeration.get(params['id']);
println "before:"
enumeration.enumerationValues.each() { enumValue ->
enumValue.enumerationValueTranslations.each() { enumValueTr ->
println enumValueTr;
if(!enumValueTr.validate()) {
// print errors...
}
}
}
// swap languages:
// (this are the lines of codes that are actually executed, and cause the
// error. The actual processing of params looks different of course...)
// sets the language of "Comedy" to English
EnumerationValueTranslation.get(5).language = Language.get(1);
// sets the language of "Komödie" to German
EnumerationValueTranslation.get(6).language = Language.get(2);
println "after:"
enumeration.enumerationValues.each() { enumValue ->
enumValue.enumerationValueTranslations.each() { enumValueTr ->
println enumValueTr;
if(!enumValueTr.validate()) {
// print errors...
}
}
}
wich results to:
before:
EnumerationValueTranslation(value: Fantasy, language: en_US, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Phantasie, language: de_DE, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Comedy, language: de_DE, enumerationValue: Comedy)
EnumerationValueTranslation(value: Komödie, language: en_US, enumerationValue: Comedy)
after:
EnumerationValueTranslation(value: Fantasy, language: en_US, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Phantasie, language: de_DE, enumerationValue: Fantasy)
EnumerationValueTranslation(value: Comedy, language: en_US, enumerationValue: Comedy)
validation fails: Property [language] of class [Translation] with value [Language(code: en_US)] must be unique
EnumerationValueTranslation(value: Komödie, language: de_DE, enumerationValue: Comedy)
validation fails: Property [language] of class [Translation] with value [Language(code: de_DE)] must be unique
at this state i havend deleted, or saved (or flushed in any way) anything - this is just the result after altering the objects. And as you can see, there really is no inconsistency in the actual data and the validation should'nt fail.
Might there be a mistake in the way i change the translations? I just fetched them by ID and simply updated the language - i tryed that out in a minimalistic example and it worked there...
It also works if i just create a deep copy of all enumeration-values and enumeration-value-translations and store that instead (which means that the validation really should'nt fail), but i think this is really not the way it should be done...
Another strange thing is, that the validation only fails if I iterate through the data. If i dont touch the data at all, no error occures, but the data isn't saved too, meaning that the folowing lines are causing the validations to be evaluated at all:
enumeration.enumerationValues.each() { ev ->
ev.enumerationValueTranslations.each() { evt ->
}
}
thats why i strongly believe that there must be some non-trivial problem... please let me know if there is anything else you need to know.
thanks for any help
Let me take another try :)
I'm looking at UniqueConstraint.processValidate(), and can suppose that its logic does not consider the exchange case.
Particularly, the code
boolean reject = false;
if (id != null) {
Object existing = results.get(0);
Object existingId = null;
try {
existingId = InvokerHelper.invokeMethod(existing, "ident", null);
}
catch (Exception e) {
// result is not a domain class
}
if (!id.equals(existingId)) {
reject = true;
}
}
else {
reject = true;
}
should iterate the obtained results and verify that the field value STILL violates uniqueness. In case of exchange, the other instance should be picked from a cache and have a new field value.
So I'd suggest you create an own descendant of UniqueConstraint and use it, unless anyone's going to patch Grails.
I have a command object that captures a feedback form with 3 textareas.
class FeedbackCommand {
String textarea1
String textarea2
String textarea3
String username
static constraints = {
textarea1(nullable:true, blank:true)
textarea2(nullable:true, blank:true)
textarea3(nullable:true, blank:true)
username(nullable:false, blank:false)
}
}
I'd like to ensure that at least ONE of the textareas is filled out.
I came up with adding a fake flag field as a 'constraint' field, and then doing a bunch of object checks in the custom validator for that field. If after looking around in myself and i dont find what I want, I throw an error.
Right now, I'm doing this:
class FeedbackCommand {
String textarea1
String textarea2
String textarea3
boolean atLeastOne = true
String username
static constraints = {
textarea1(nullable:true, blank:true)
textarea2(nullable:true, blank:true)
textarea3(nullable:true, blank:true)
atLeastOne(validator: { boolean b, FeedbackCommand form, Errors err ->
if (b) {
if ( (form.textarea1==null || form.textarea1?.isAllWhitespace()) &&
(form.textarea2==null || form.textarea2?.isAllWhitespace()) &&
(form.textarea3==null || form.textarea3?.isAllWhitespace()))
{
// They havent provided ANY feedback. Throw an error
err.rejectValue("atLeastOne", "no.feedback")
return false
}
}
return true
})
username(nullable:false, blank:false)
}
}
Is there a better way to
validate a related/group of fields (at least one can't be blank, 2 should have values, etc)?
a groovier way to express "at least one shouldnt be null/blank" rather than my gross if-statement block?
Thanks
The Extended Validation plugin also adds support for instance validators, which allow to define constraints over several field without defining an artificial flag field or without repeating the validator for each field involved.
validate a related/group of fields (at least one can't be blank, 2 should have values, etc)?
Try this:
if ( (form.textarea1?.trim() ? 1 : 0) +
(form.textarea2?.trim() ? 1 : 0) +
(form.textarea3?.trim() ? 1 : 0) < 2) {
err.rejectValue("atLeastTwo", "no.feedback")
return false
}
a groovier way to express "at least one shouldnt be null/blank" rather than my gross if-statement block?
This is slightly Groovier...
if (!( (form.textarea1?.trim() ?: 0) ||
(form.textarea2?.trim() ?: 0) ||
(form.textarea3?.trim() ?: 0) )) {
err.rejectValue("atLeastOne", "no.feedback")
return false
}
WRT validating a group of fields, you could assign the validator closure to one of the fields. You don't need any extra/ficticious field.
If it's going to be used often, create a plugin
http://www.zorched.net/2008/01/25/build-a-custom-validator-in-grails-with-a-plugin/
or use a plugin for constraints
http://grails.org/plugin/constraints
About grooviness I'm not an expert. But the safe navigator operator ?. makes unnecessary to ask for null
if ( form.textarea1?.isAllWhitespace() &&
form.textarea2?.isAllWhitespace() &&
form.textarea3?.isAllWhitespace() )
{
// They havent provided ANY feedback. Throw an error
err.rejectValue("atLeastOne", "no.feedback")
return false
}
You can use the min-criteria plugin for that.
http://www.grails.org/plugin/min-criteria
My problem is simple but I could not find any GORM syntax for this.
Consider the following class:
class Article {
String text
static hasMany = [tags: String]
static constraints= {
tags(unique: true) //NOT WORKING
}
}
I want to have one unique tag name per article defined in my constraints but I cannot make it with the above syntax.
Clearly I need in DB schema something like:
create table article_tags (article_id bigint, tags_string varchar(255), unique (article_id , tags_string))
How can I do that?
PS: I am also stuck for setting constraints on tag minimum and maximum size
FYI, you can also use a custom validator in domain classes:
static constraints = {
tags(validator: {
def valid = tags == tags.unique()
if (!valid) errors.rejectValue(
"tags", "i18n.message.code", "default message")
return valid
})
At the database level, you can customize DDL generation by having the following code in grails-app/conf/hibernate/hibernate.cfg.xml:
<hibernate-mapping>
<database-object>
<create>
ALTER TABLE article_tags
ADD CONSTRAINT article_tags_unique_constraint
UNIQUE(article_id, tags_string);
</create>
<drop>
ALTER TABLE article_tags
DROP CONSTRAINT article_tags_unique_constraint;
</drop>
</database-object>
</hibernate-mapping>
Initially I looked at the joinTable mapping to see if it would support a unique key, but it won't.
The best solution I can think of is the following combination:
Manually run the SQL statement to add the unique constraint. If you have some sort of database management tool (e.g. Liquibase), that would be the ideal place.
Explicitly declare the association as a Set. This should avoid Hibernate ever running into the unique constraint, anyway.
class Article {
static hasMany = [tags: String]
Set<String> tags = new HashSet<String>()
}
An alternate solution would be to explicitly declare your child domain (Tag) and set up a many-to-many relationship, adding the unique key to the join table there using constraints. But that's not really a great solution, either. Here's a primitive example:
class Article {
static hasMany = [articleTags: ArticleTag]
}
class Tag {
static hasMany = [articleTags: ArticleTag]
}
class ArticleTag {
Article article
Tag tag
static constraints = {
tag(unique: article)
}
}
With this, though, you have to explicitly manage the many-to-many relationship in your code. It's a bit inconvenient, but it gives you full control over the relationship as a whole. You can find out the nitty gritty details here (the Membership class in the linked example is akin to the ArticleTag in mine).
Perhaps one of the gurus more familiar with GORM will chime in with a more elegant solution, but I can't find anything in the docs.
EDIT: Note that this approach does not consider a unique(article_id , tags_id) constraint. It also raises an issue with two Articles having the same tags. - Sorry.
While this is not officially documented (see the relevant parts of the Grails Reference Documentation here and here) constraints on one-to-many associations are simply ignored by GORM. This includes unique and nullable constraints, and probably any.
This can be proved by setting dbCreate="create" and next, by looking at the database schema definition. For your Article sample and the PostgreSQL database, this would be:
CREATE TABLE article_tags
(
article_id bigint NOT NULL,
tags_string character varying(255),
CONSTRAINT fkd626473e45ef9ffb FOREIGN KEY (article_id)
REFERENCES article (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT article0_tags_article0_id_key UNIQUE (article_id)
)
WITH (
OIDS=FALSE
);
As can be seen above, there are no constraints for the tags_string column.
In contrast to constraints on association fields, constraints on "normal" instance fields of domain classes do work as expected.
Thus, we'll want to have some kind of Tag, or TagHolder, domain class, and we'd need to find a pattern that still provides the Article with a clean public API.
First, we're introducing the TagHolder domain class:
class TagHolder {
String tag
static constraints = {
tag(unique:true, nullable:false,
blank:false, size:2..255)
}
}
and associate it with the Article class:
class Article {
String text
static hasMany = [tagHolders: TagHolder]
}
In order to provide a clean public API, we're adding the methods String[] getTags(), void setTags(String[]. That way, we can also call the constructor with named parameters, like, new Article(text: "text", tags: ["foo", "bar"]). We're also adding the addToTags(String) closure, which mimicks GORM's corresponding "magic method".
class Article {
String text
static hasMany = [tagHolders: TagHolder]
String[] getTags() {
tagHolders*.tag
}
void setTags(String[] tags) {
tagHolders = tags.collect { new TagHolder(tag: it) }
}
{
this.metaClass.addToTags = { String tag ->
tagHolders = tagHolders ?: []
tagHolders << new TagHolder(tag: tag)
}
}
}
It's a workaround, but there's not too much coding involved.
A drawback, we're getting an additional JOIN table. Nevertheless, this pattern allows for applying any available constraints.
Finally, a test case could look like this one:
class ArticleTests extends GroovyTestCase {
void testUniqueTags_ShouldFail() {
shouldFail {
def tags = ["foo", "foo"] // tags not unique
def article = new Article(text: "text", tags: tags)
assert ! article.validate()
article.save()
}
}
void testUniqueTags() {
def tags = ["foo", "bar"]
def article = new Article(text: "text", tags: tags)
assert article.validate()
article.save()
assert article.tags.size() == 2
assert TagHolder.list().size() == 2
}
void testTagSize_ShouldFail() {
shouldFail {
def tags = ["f", "b"] // tags too small
def article = new Article(text: "text", tags: tags)
assert ! article.validate()
article.save()
}
}
void testTagSize() {
def tags = ["foo", "bar"]
def article = new Article(text: "text", tags: tags)
assert article.validate()
article.save()
assert article.tags.size() == 2
assert TagHolder.list().size() == 2
}
void testAddTo() {
def article = new Article(text: "text")
article.addToTags("foo")
article.addToTags("bar")
assert article.validate()
article.save()
assert article.tags.size() == 2
assert TagHolder.list().size() == 2
}
}
Try this:
http://johnrellis.blogspot.com/2009/09/grails-constraints-across-relationships.html
The only way I've found to do this is to write a custom constraint and do a database check for the duplication. I don't think there is a built-in way to use a GORM constraint to accomplish this.