bindData() is changing the domain id when using gorm inheritance - grails-orm

I have a grails domain class that extends a base class in the src folder, like so:
// src/main/groovy/demo/MyBaseClass.groovy
package demo
import grails.gorm.dirty.checking.DirtyCheck
#DirtyCheck
class MyBaseClass {
String name
}
// grails-app/domain/demo/MyDomain.groovy
package demo
class MyDomain extends MyBaseClass {
Date birthDate
}
However, when using bindData in the controller, the id of MyDomain can be changed by the request params. This can be checked with this failing test:
// src/test/groovy/demo/IdDataBindingSpec.groovy
package demo
import grails.web.databinding.DataBinder
import org.grails.testing.GrailsUnitTest
import spock.lang.Specification
class IdDataBindingSpec extends Specification
implements GrailsUnitTest, DataBinder {
void "Bind id to MyDomain is not possible"() {
given: "A new instance"
MyDomain myDomain = new MyDomain()
and: "Request params"
Map params = [id:5, name:'test']
when: "Binding data"
bindData(myDomain, params)
then: "id is not updated"
!myDomain.id
and: "Other params are updated"
myDomain.name == 'test'
}
}
Any normal domain will pass the above test, but the domain extending a base class from src will not. How can i fix this behavior?
Edit: I'm using Grails 3.3.8 with gorm 6.1

When using gorm inheritance, the base classes in src must be declared as abstract, like so:
// src/main/groovy/demo/MyBaseClass.groovy
package demo
import grails.gorm.dirty.checking.DirtyCheck
#DirtyCheck
abstract class MyBaseClass {
String name
}

Related

How do I declare field variable of tested class using apache velocity?

I'm trying to setup intellij idea code template for JUnit4 Test Class so that when I create the test it will also generate a field variable in the test. Example :
public class FooTest {
private Foo foo;
...
}
The problem I'm having is using the $CLASS_NAME variable to set the field name with lower camel case.
You can do a toLowerCase() of first character. Sample below for reference.
import static org.junit.Assert.*;
#parse("File Header.java")
public class ${NAME} {
${BODY}
#set($var_name = ${NAME})
#set($var_name = $var_name.substring(0,1).toLowerCase() + $var_name.substring(1))
private ${CLASS_NAME} $var_name;
}

bytecode tools: add method interceptor to classes (not proxy)

Javassist proxyFactory can create proxy at runtime with method interceptor. But how to add method interceptor to a class statically by modifying the class file?
For example, class Foo has 100 methods, before calling any method on an instance of Foo, need to check if the Foo instance is initialized.
public class Foo {
public void methodA() {
...
}
public void methodB() {
...
}
public void methodC() {
...
}
....
}
How to modify the class file to add such method interceptor? One way is to add code at the beginning of each method. Is there a better way?
How about other bytecode tools such as cglib, ....?
There are two options with ByteBuddy to achive this:
use redefine/rebase feature - You can check the details on ByteBuddy tutorial under 'type redefinition'/'type rebasing' tags. Limitation here is that this kind of transformation needs to be done before a target class is loaded.
Java Agent - agents run before class is loaded so they are allowed to modify existing classes. ByteBuddy comes with nice AgentBuilder (tutorial - 'Creating Java agents'). There is also posiblity to install special ByteBuddy agent at runtime (example from mentioned tutorial).
class Foo {
String m() { return "foo"; }
}
class Bar {
String m() { return "bar"; }
}
ByteBuddyAgent.install();
Foo foo = new Foo();
new ByteBuddy()
.redefine(Bar.class)
.name(Foo.class.getName())
.make()
.load(Foo.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
assertThat(foo.m(), is("bar"));

Interface inheriting Type script

I just want to write a User module which has multiple classes i.e. UserDetail,UserResestPassword so on .
There are some common properties which these classes are going to share , one approach I can declare property on every class and Initialize it.
The second approach is I will use of inheritance this will need to declare in
interface
export interface Iuser {
UserID:string;
UserName:string
}
and implement it into classes
import {Iuser} from './IuserDetail'
class UserInfo implements Iuser {}
My question is, is't supported in typescript? if not what are the way around to sort out this
In TypeScript there is a feature called "type erasure" where all of the type information is removed during compilation so the JavaScript output contains no type annotations, interfaces, or ambient declarations - only real code.
This means that when you ask your module loader (at runtime) to get you the Iuser interface, it doesn't exist in the JavaScript file.
My recommendation would probably be to put your interfaces in files with their primary implementation. That means you don't end up attempting to load a module that is just a blank file.
For example:
export interface Iuser {
UserID:string;
USerName:string
}
export class UserInfo implements Iuser {
}
And in other files you can:
import * as User from './UserInfo'
export class Example implements User.Iuser {
}
Look at this example:
Interfaces don't actually exist after compilation but are strictly used for type checking.
// i-user.ts
export interface IUser {
UserID:string;
UserName:string
}
Just like interfaces in other languages you have to implement all members of an interface. TypeScript will check if you are missing any.
// user-info.ts
import { IUser } from './i-user'
export class UserInfo implements IUser {
UserID:string;
UserName:string;
OtherInfo:string;
}
Using extend all parent methods will be available and you don't need to implement them again.
// specific-user-info.ts
import { UserInfo } from './user-info'
class SpecificUserInfo extends UserInfo {
logInfo() {
console.log(this.UserID, this.UserName);
}
}

JsonIgnoreProperties not working

I have the following simple class:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
#JsonIgnoreProperties({ "thirdField" })
public class Message {
private TypeA type;
private String producer;
//Getters and Setters
}
in my test class
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Test {
public void testMethd() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(MapperFeature.USE_ANNOTATIONS, true);
Class<T> instanceType = Message.class;
String msgBody = "{\"producer\": \"clientApp\", \"type\": \"aType\", \"thirdField\": []}";
objectMapper.readValue(msgBody, instanceType);
}
}
All I am trying to do is to convert the above json string into Message class and ignore the 'thirdField'. But I keep getting
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "thirdField" (class Message), not marked as ignorable (2 known properties: , "type", "producer"])
You've mixed different versions of Jackson.
Notice that you import JsonIgnoreProperties from org.codehaus.jackson.annotate (version 1.x)
while you're using ObjectMapper from com.fasterxml.jackson.databind (version 2.x).
Try using the last Jackson version (2.4):
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
#JsonIgnoreProperties({"id"})
Here you can find an example where it's implement using version 2.4:
http://www.ibm.com/developerworks/java/library/j-hangman-app/index.html
I found a Solution to this.
Try to add
#JsonSerialize(include= JsonSerialize.Inclusion.NON_EMPTY)
About your class
#JsonSerialize(include= JsonSerialize.Inclusion.NON_EMPTY)
class ResponseModel {
//your properties here
#JsonIgnoreProperties("messageList","contactList","sender")
var contactList= ArrayList<ContactModel>()
}
That will solve your issue buddy.
It didn't work for me any of the above answers, i found a workaround that I have reinitialized the object and values (copied the object).

Spring LDAP ODM - Entry class should be declared final Warning

I have a mapped Entry ("entity") using Spring LDAP ODM. When I run unit tests with this class, I get a warning in the console upon initialization:
Mar 9, 2012 2:32:40 PM org.springframework.ldap.odm.core.impl.ObjectMetaData <init>
WARNING: The Entry class Superhero should be declared final
The mapped class looks like this:
#Entry(objectClasses = {"batman", "superman", "spiderman", "dontworryaboutthese"})
public class Superhero {
#Id
#JsonIgnore
private Name dn;
...
I can't find anything relevant via Google search regarding this warning. Here's the Spring code that logs it:
public ObjectMetaData(Class<?> clazz) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Extracting metadata from %1$s", clazz));
}
// Get object class metadata - the #Entity annotation
Entry entity = (Entry)clazz.getAnnotation(Entry.class);
if (entity != null) {
// Default objectclass name to the class name unless it's specified
// in #Entity(name={objectclass1, objectclass2});
String[] localObjectClasses = entity.objectClasses();
if (localObjectClasses != null && localObjectClasses.length > 0 && localObjectClasses[0].length() > 0) {
for (String localObjectClass:localObjectClasses) {
objectClasses.add(new CaseIgnoreString(localObjectClass));
}
} else {
objectClasses.add(new CaseIgnoreString(clazz.getSimpleName()));
}
} else {
throw new MetaDataException(String.format("Class %1$s must have a class level %2$s annotation", clazz,
Entry.class));
}
// Check the class is final
if (!Modifier.isFinal(clazz.getModifiers())) {
LOG.warn(String.format("The Entry class %1$s should be declared final", clazz.getSimpleName()));
}
...
Any insight would be appreciated. I understand that declaring a class as final means it can't be extended, but why would Spring ODM care?
Security reason ?
Maybe by subclassing your entity, one could store other kind of LDAP entries in the directory, leading to unforseen behavior ?