This is a newbie question -- thank you for your help. I wanted to set a derived property to lower case in my domain model. Did some search (http://grails.org/doc/latest/guide/GORM.html#ormdsl plus some other) and I thought the following would work (note: nameLowerCase formula: 'LOWER(NAME)') ...
class Item {
String name
String nameLowerCase
static constraints = {
name(blank: false)
nameLowerCase(blank: false, unique: true)
}
static mapping = {
nameLowerCase formula: 'LOWER(NAME)'
sort nameLowerCase: "asc"
}
}
However, when I do ...
new Item(name: 'A').save(failOnError: true)
new Item(name: 'c').save(failOnError: true)
new Item(name: 'B').save(flush: true, failOnError: true)
println Item.list().nameLowerCase
I was expecting it to print [a, b, c] (turning to lower case in addition to the sorting), but it prints [null, null, null], and I am unable to figure out why.
What am I doing wrong? Or, is there any other way I can achieve the lower case in my domain class itself for nameLowerCase irrespective of what is passed for the name (other than using the formula in mapping)? Any help will be appreciated.
I think storing the same data in the database is a bad idea.
It's better to do it this way:
class Item {
static transients = ['nameLoweCase']
String name
String getNameLowerCase(){
name.toLowerCase()
}
static constraints = {
name blank: false
}
}
And in the controller:
class SomeController{
def show(Long id){
def item = Item.get(id)
item.nameLowerCase // name in lower case
}
}
'transient' defines a list of property names that should not be persisted to the database (more about it).
Just add this
def beforeInsert() {
nameLowerCase = name.toLowerCase()
}
def beforeUpdate() {
nameLowerCase = name.toLowerCase()
}
and remove this
nameLowerCase formula: 'LOWER(NAME)'
and Enjoy..
Related
This might be a duplicate. But I cannot find a solution to my Problem.
I have a class
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Getters and setters are generated by Eclipse.
In another class, I set the value to true, and write it as a JSON string.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
In JSON, the key is coming as {"success": true}.
I want the key as isSuccess itself. Is Jackson using the setter method while serializing? How do I make the key the field name itself?
This is a slightly late answer, but may be useful for anyone else coming to this page.
A simple solution to changing the name that Jackson will use for when serializing to JSON is to use the #JsonProperty annotation, so your example would become:
public class MyResponse implements Serializable {
private boolean isSuccess;
#JsonProperty(value="isSuccess")
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
This would then be serialised to JSON as {"isSuccess":true}, but has the advantage of not having to modify your getter method name.
Note that in this case you could also write the annotation as #JsonProperty("isSuccess") as it only has the single value element
I recently ran into this issue and this is what I found. Jackson will inspect any class that you pass to it for getters and setters, and use those methods for serialization and deserialization. What follows "get", "is" and "set" in those methods will be used as the key for the JSON field ("isValid" for getIsValid and setIsValid).
public class JacksonExample {
private boolean isValid = false;
public boolean getIsValid() {
return isValid;
}
public void setIsValid(boolean isValid) {
this.isValid = isValid;
}
}
Similarly "isSuccess" will become "success", unless renamed to "isIsSuccess" or "getIsSuccess"
Read more here: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
Using both annotations below, forces the output JSON to include is_xxx:
#get:JsonProperty("is_something")
#param:JsonProperty("is_something")
When you are using Kotlin and data classes:
data class Dto(
#get:JsonProperty("isSuccess") val isSuccess: Boolean
)
You might need to add #param:JsonProperty("isSuccess") if you are going to deserialize JSON as well.
EDIT: If you are using swagger-annotations to generate documentation, the property will be marked as readOnly when using #get:JsonProperty. In order to solve this, you can do:
#JsonAutoDetect(isGetterVisibility = JsonAutoDetect.Visibility.NONE)
data class Dto(
#field:JsonProperty(value = "isSuccess") val isSuccess: Boolean
)
You can configure your ObjectMapper as follows:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
return method.getName();
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
I didn't want to mess with some custom naming strategies, nor re-creating some accessors.
The less code, the happier I am.
This did the trick for us :
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates
public class MyResponse {
private String id;
private #JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name
private #JsonProperty("isDeleted") boolean isDeleted;
}
Building upon Utkarsh's answer..
Getter names minus get/is is used as the JSON name.
public class Example{
private String radcliffe;
public getHarryPotter(){
return radcliffe;
}
}
is stored as { "harryPotter" : "whateverYouGaveHere" }
For Deserialization, Jackson checks against both the setter and the field name.
For the Json String { "word1" : "example" }, both the below are valid.
public class Example{
private String word1;
public setword2( String pqr){
this.word1 = pqr;
}
}
public class Example2{
private String word2;
public setWord1(String pqr){
this.word2 = pqr ;
}
}
A more interesting question is which order Jackson considers for deserialization. If i try to deserialize { "word1" : "myName" } with
public class Example3{
private String word1;
private String word2;
public setWord1( String parameter){
this.word2 = parameter ;
}
}
I did not test the above case, but it would be interesting to see the values of word1 & word2 ...
Note: I used drastically different names to emphasize which fields are required to be same.
You can change primitive boolean to java.lang.Boolean (+ use #JsonPropery)
#JsonProperty("isA")
private Boolean isA = false;
public Boolean getA() {
return this.isA;
}
public void setA(Boolean a) {
this.isA = a;
}
Worked excellent for me.
If you are interested in handling 3rd party classes not under your control (like #edmundpie mentioned in a comment) then you add Mixin classes to your ObjectMapper where the property/field names should match the ones from your 3rd party class:
public class MyStack32270422 {
public static void main(String[] args) {
ObjectMapper om3rdParty = new ObjectMapper();
om3rdParty .addMixIn(My3rdPartyResponse.class, MixinMyResponse.class);
// add further mixins if required
String jsonString = om3rdParty.writeValueAsString(new My3rdPartyResponse());
System.out.println(jsonString);
}
}
class MixinMyResponse {
// add all jackson annotations here you want to be used when handling My3rdPartyResponse classes
#JsonProperty("isSuccess")
private boolean isSuccess;
}
class My3rdPartyResponse{
private boolean isSuccess = true;
// getter and setter here if desired
}
Basically you add all your Jackson annotations to your Mixin classes as if you would own the class. In my opinion quite a nice solution as you don't have to mess around with checking method names starting with "is.." and so on.
there is another method for this problem.
just define a new sub-class extends PropertyNamingStrategy and pass it to ObjectMapper instance.
here is a code snippet may be help more:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
String input = defaultName;
if(method.getName().startsWith("is")){
input = method.getName();
}
//copy from LowerCaseWithUnderscoresStrategy
if (input == null) return input; // garbage in, garbage out
int length = input.length();
StringBuilder result = new StringBuilder(length * 2);
int resultLength = 0;
boolean wasPrevTranslated = false;
for (int i = 0; i < length; i++)
{
char c = input.charAt(i);
if (i > 0 || c != '_') // skip first starting underscore
{
if (Character.isUpperCase(c))
{
if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_')
{
result.append('_');
resultLength++;
}
c = Character.toLowerCase(c);
wasPrevTranslated = true;
}
else
{
wasPrevTranslated = false;
}
result.append(c);
resultLength++;
}
}
return resultLength > 0 ? result.toString() : input;
}
});
The accepted answer won't work for my case.
In my case, the class is not owned by me. The problematic class comes from 3rd party dependencies, so I can't just add #JsonProperty annotation in it.
To solve it, inspired by #burak answer above, I created a custom PropertyNamingStrategy as follow:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if (method.getParameterCount() == 1 &&
(method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) &&
method.getName().startsWith("set")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = "is" + method.getName().substring(3);
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForSetterMethod(config, method, defaultName);
}
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = method.getName();
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
Basically what this does is, before serializing and deserializing, it checks in the target/source class which property name is present in the class, whether it is isEnabled or enabled property.
Based on that, the mapper will serialize and deserialize to the property name that is exist.
I know it's a silly question but I'm stuck on it for quite a while now.
How to set default values of class members in DART.
This is how i provide the default values of the members but it's always null.
If these values are provided in constructor then it should use those values otherwise use the default value.
class BillingInfoDetails {
bool billToClient = false;
String clientName = "";
String reasonOfTravel = "";
String remarks = "";
BillingInfoDetails({
this.billToClient,
this.clientName,
this.reasonOfTravel,
this.remarks,
});
}
Like this:
class BillingInfoDetails {
bool billToClient;
String clientName;
String reasonOfTravel;
String remarks;
BillingInfoDetails({
this.billToClient = false,
this.clientName = "",
this.reasonOfTravel = "",
this.remarks = "",
});
}
You can find this information in the Dart Tour Guide: https://dart.dev/guides/language/language-tour#parameters in section "Default parameter values".
I'm trying to create a static index where I want all documents where a key exists and has a value. The value itself is not important, only the key exists.
I'm exploring this example with dynamic fields:
https://ravendb.net/docs/article-page/2.5/csharp/client-api/advanced/dynamic-fields
... and although I'm getting the index to work, I'm not sure if the query I'm using is correct.
This is the sample class:
public class Result
{
public Dictionary<string, List<Data>> Results { get; set; }
}
The key in the dictionary is the ID of a user (for example "user/1") and the value is a list of data-objects. The so the json-structure looks like this:
{
"Results" :
{
"user/1": [{...}],
"user/2": [{...}],
}
}
The index I use is this:
public class Result_ByUserId : AbstractIndexCreationTask<Result>
{
public Result_ByUserId()
{
Map = res => from r in res
select new
{
_ = r.Results
.Select(d => CreateField(d.Key, d.Value))
};
}
}
My problem comes down to the query, as it assumes I want to look at a specific key and value.
var resultat = session.Advanced.DocumentQuery<Result>("Result/ByUserId ")
.WhereEquals("user/1", "") // How do I write a !isNullOrEmpty?
.ToList();
... which I don't want to do. I only want the results that has a key in which the value is not null or empty. Does anybody have any good tips?
What you can do is index a boolean flag depending on if the dictionary has a value or not and then query on that.
public class Result_ByUserId : AbstractIndexCreationTask<Result>
{
public Result_ByUserId()
{
Map = res => from r in res
select new
{
_ = r.Results
.Select(d => CreateField(d.Key, d.Value != null ? true : false, false, true))
};
}
}
The query can then be:
var resultat = session.Advanced.DocumentQuery<Result>("Result/ByUserId ")
.WhereEquals("user/1", true)
.ToList();
This will return any Result documents that has a Dictionary with a key of user/1 and a dictionary value that's not null.
Not sure it's the best way of doing it, but it worked for me...
Hope this helps!
I will be displaying some results that will be either 0 or 1 in my MVC 4 application. I would like for them to display either yes (1) or no (0). Is there an annotation I can add to my fields to do that? Or do I have to do that in the view somehow...
In the model, add a backing field and specify the getter for the property
private string _myString;
public string MyString
{
get
{
_myString = _myString.Equals( "0" ) ? "No" : "Yes";
return _myString;
}
set { _myString = value; }
}
You could use a custom HTML helper for this:
http://www.asp.net/mvc/tutorials/older-versions/views/creating-custom-html-helpers-cs
or perhaps just a plain extension method. I have one I use for Boolean values.
public static bool ToYesNo(this Boolean boolValue)
{
return (boolValue ? "Yes" : "No");
}
Dart specification states:
Reified type information reflects the types of objects at runtime and may always be queried by dynamic typechecking constructs (the
analogs of instanceOf, casts, typecase etc. in other languages).
Sounds great, but there is no instanceof-like operator. So how do we perform runtime type-checking in Dart? Is it possible at all?
The instanceof-operator is called is in Dart. The spec isn't exactly friendly to a casual reader, so the best description right now seems to be http://www.dartlang.org/articles/optional-types/.
Here's an example:
class Foo { }
main() {
var foo = new Foo();
if (foo is Foo) {
print("it's a foo!");
}
}
Dart Object type has a runtimeType instance member (source is from dart-sdk v1.14, don't know if it was available earlier)
class Object {
//...
external Type get runtimeType;
}
Usage:
Object o = 'foo';
assert(o.runtimeType == String);
As others have mentioned, Dart's is operator is the equivalent of Javascript's instanceof operator. However, I haven't found a direct analogue of the typeof operator in Dart.
Thankfully the dart:mirrors reflection API has recently been added to the SDK, and is now available for download in the latest Editor+SDK package. Here's a short demo:
import 'dart:mirrors';
getTypeName(dynamic obj) {
return reflect(obj).type.reflectedType.toString();
}
void main() {
var val = "\"Dart is dynamically typed (with optional type annotations.)\"";
if (val is String) {
print("The value is a String, but I needed "
"to check with an explicit condition.");
}
var typeName = getTypeName(val);
print("\nThe mirrored type of the value is $typeName.");
}
There are two operators for type testing: E is T tests for E an instance of type T while E is! T tests for E not an instance of type T.
Note that E is Object is always true, and null is T is always false unless T===Object.
Exact type matching is done via runtimeType property. Checking if an instance or any of its parent types (in the inheritance chain) is of the given type is done via is operator:
class xxx {}
class yyy extends xxx {}
void main() {
var y = yyy();
print(y is xxx);
print(y.runtimeType == xxx);
}
Returns:
true
false
Simply use .runtimeType on the property like below,
print(unknownDataTypeProperty.runtimeType)
Just to clarify a bit the difference between is and runtimeType. As someone said already (and this was tested with Dart V2+) the following code:
class Foo {
#override
Type get runtimeType => String;
}
main() {
var foo = Foo();
if (foo is Foo) {
print("it's a foo!");
}
print("type is ${foo.runtimeType}");
}
will output:
it's a foo!
type is String
Which is wrong.
Now, I can't see the reason why one should do such a thing...
T is The type
print( T.runtimeType)
if(value is int ) Returns true if the type of the value is int,
else if(value is! int )
To check the type of a variable use runtimeType
void main() {
int a = 10;
print(a.runtimeType);
}
to check whether the type of a variable is the same as your expected use is or runtimeType
void main() {
int a = 10;
print(a.runtimeType == int); // true
//or
print(a is int); // true
}
print("enter your phone number:\n");
var phone number = stdin.readLineSync();
if(phone number.runtimeType is int == true) // checks if the values input are integers
{
print('you have successfully input your phone number!');
}
else{
print('only numbers are allowed');
}