Modelmapper map field of one object to another object - modelmapper

Can I somehow tell ModelMapper to map all properties of a field of an object to another object? For example (assume getters and setters):
public class Foo {
private String data;
}
public class FooContainer {
private Foo foo;
}
public class Bar {
private String data;
}
I can map 'data' from a FooContainer to a Bar by using fooContainer.getFoo() as the source but is there a way to make some sort of type or property map that does this automagically without me having to do that everywhere?

Related

Creating anonymous object with inline function. Does it contain a leak of Enclosing Class?

As you know each anonymous object in java contains hidden reference to enclosing class.
But with kotling things get more complicated.
Lambda is another representation of anonymous class, but in kotlin it compiles not straightforward, because if lambda didn't capture a reference of enclosing class explicitely than it would be compiled like nested, not inner class (anonymous class) and is safe from the leak.
But what about inline functions. Consider the code below
class A {
fun test(){
val it = withReference {
//todo make sth
}
}
}
inline fun withReference(crossinline action: () -> Unit) = object: Reference {
override fun method1() {
action()
}
override fun method2() {
}
}
interface Reference {
fun method1()
fun method2()
}
As i know inline function would be compiled like non-wrapped code to the A class, so the question is open.
Does the anonymous object: Reference contain a link to enclosing class A, which could lead to a memory leak?
PS: i have read this article, but it doesn't contain an answer to my case
I used the decompiler of IntelliJ and there is no reference to the outer A
public final class A$test$$inlined$withReference$1 implements Reference {
public void method1() {
}
public void method2() {
}
}
If the lambda references a variable from the outer class A like this:
class A {
val valFromA = 10;
fun test(){
val it = withReference {
println("use $valFromA")
}
}
}
Then the decompiler shows the reference to the A object:
public final class A$test$$inlined$withReference$1 implements Reference {
// $FF: synthetic field
final A this$0;
public A$test$$inlined$withReference$1(A var1) {
this.this$0 = var1;
}
public void method1() {
String var1 = "use " + this.this$0.getValFromA();
System.out.println(var1);
}
public void method2() {
}
}
If you think about it, the withReference function has no way of referring to the outer scope that it gets inlined into, therefore it has no reason to contain a reference to the scope that it's called from. You don't even know what class it's being called in, or if it's even called inside a class, for that matter.
For this specific case, here's the decompiled and simplified bytecode of the withReference function:
public static Reference withReference(final Function0 action) {
return new Reference() {
public void method1() {
action.invoke();
}
public void method2() {
}
};
}
At the places where it gets inlined, there's of course no call to this function, this one is for Java interop only. Kotlin call sites all get their own class generated to represent this object depending on what code you pass into the action parameter. For your call of the test function, a class like is generated:
public final class A$test$$inlined$withReference$1 implements Reference {
public void method1() {
//todo make sth
}
public void method2() {
}
}
And this is what's instantiated in the test method:
public final class A {
public final void test() {
Reference it = new A$test$$inlined$withReference$1();
}
}

Modelmapper circular mapping

I've parent and child class with respective DTO's as follows
class Parent {
List<Child> children;
// setters and getters
}
class Child {
Parent parent;
}
class ParentDto {
List<ChildDto> children;
// setters and getters
}
class ChildDto {
ParentDto parent;
// setters and getters
}
When I try to map Parent to ParentDto I'm getting StackOverflowError.
Please help me in resolving the issue.
I know this post is old but I will try to give one answer in case someone from google to arrived here.
Probably you have a dynamic object creation.
Recently I had a problem like this. In my case I have a class Student that extends Person. And Person has three others attributes of type Person: father, mother and responsible. In case, I had a circularity relationship. When I ran my JUnits tests I got a circularity calls. I did't get a stakOverflow because the Spring (after some time) closes the data base connections.
I resolved this problem removing the dynamics objects creations from my Person class.
Another approach to solve this problem is adding a Condition in your mapper. You can read more about conditions here. For example, you can have some Conditions saying: "If the person attribute id is 10, then, doesn't need map it.". This way we can avoid infinity mapping.
Well, let's see some snippeds of code:
Student class:
public class Student extends Person implements IStudent {
private Person financialResponsible;
// Getters and setters.
}
Person class:
public class Person implements IPerson {
private Long id;
private String name;
private Person father;
private Person mother;
private Person responsible;
private Address address;
// Getters and setters.
// This is my real problem. I removed it and the mapper worked.
public IPerson getFather() {
if (father == null) father = new Person();
return father;
}
}
StudentDTO class:
public class StudentDTO extends PersonDTO {
private PersonDTO financialResponsible;
// Getters and setters.
}
PersonDTO class:
public class PersonDTO {
private Long id;
private String name;
private PersonDTO father;
private PersonDTO mother;
private PersonDTO responsible;
private AddressDTO address;
// Getters and setters.
}
Here is a example of conditions:
...
import org.modelmapper.Condition;
...
ModelMapper mapper = new ModelMapper();
// Define STRICT to give high precision on mapper.
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
/*
* Create conditions to avoid infinity circularity.
*/
// Condidions.
final Condition<IStudent, StudentDTO> fatherIsTen = mappingContext -> mappingContext.getSource().getFather().getId() == 10;
final Condition<IStudent, StudentDTO> motherIsTen = mappingContext -> mappingContext.getSource().getMother().getId() == 10;
final Condition<IStudent, StudentDTO> resposibleIsTen = mappingContext -> mappingContext.getSource().getResponsible().getId() == 10;
// Adding conditions on mapper.
mapper.createTypeMap(IStudent.class, StudentDTO.class) //
.addMappings(mapper -> mapper.when(fatherIsTen).skip(StudentDTO::setFather))
.addMappings(mapper -> mapper.when(motherIsTen).skip(StudentDTO::setMother))
.addMappings(mapper -> mapper.when(resposibleIsTen).skip(StudentDTO::setResponsible));
I hope help o/

ArrayList with Objects which implements an Interface

I want a ArrayList, where you can add Objects , which implements an Interface.
Something like this:
ArrayList<Object implements Interface> list =
new ArrayList<Object which implements a specific Interface>();
What is the correct syntax for this?
Just set the interface as the type of the generic. Here you go the code in C#:
interface IFoo {
void foo();
}
class Foo1 : IFoo {
public void foo() {
Console.WriteLine("foo1");
}
}
class Foo2 : IFoo {
public void foo() {
Console.WriteLine("foo2");
}
}
class Program {
public static void Main() {
// IFoo type: any object implementing IFoo may go in
List<IFoo> list = new List<IFoo>();
list.Add(new Foo1());
list.Add(new Foo2());
foreach(IFoo obj in list) obj.foo(); // foo1, foo2
Console.ReadKey();
}
}

An object reference is required for the non-static field, method, or property

I have created the class name cls1 and created method called GrantAccess().but the i am not able to access _entities.it's showing the below error
"Error 1 An object reference is required for the non-static field, method, or property 'Path._entities".
public class cls1
{
private readonly DBEntities _entities;
public cls1 ()
{
if (_entities == null)
{
_entities = new DBEntities();
}
}
public static void GrantAccess()
{
if (Settings.DbLog == "1")
{
_entities.II_CCLog("Excuting the GrantAccess() Method");
}
}
}
The above method is called in some other class.
public void GetCConfig()
{
cls1.GrantAccess();
}
GrantAccess is a static method while _entities is not a static variable. So you need to make GrantAccess a non-static method or you have to make _entities a static variable.
Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.
Or create a new instance of DBEntities in the static GrantAccess method and perform your operation on this instance.
public static void GrantAccess()
{
if (Settings.DbLog == "1")
{
DBEntities entities = new DBEntities();
entities.II_CCLog("Excuting the GrantAccess() Method");
}
}
first you have to create an object of cls1 in the class where you are calling the method of the cls1 class and then with from that object reference you will be able to call the method GrantAccess();. You can create object by following way :-
variable_name = new class_name( );
You are mixing static code with instance code. If you're working with objects, don't make your method GrantAccess static:
public void GrantAccess()
{
if (Settings.DbLog == "1")
{
_entities.II_CCLog("Excuting the GrantAccess() Method");
}
}
Then you'll have to create an instance of cls1:
public void GetCConfig()
{
var instance = new cls1();
cls1.GrantAccess();
}
You should also make cls1 disposable and call .Dispose() on _entities after you're finishied using it.
public class cls1 : IDisposable
{
...
public void Dispose()
{
_entities.Dispose();
}
Put the cls1 instance into a using block, like this:
public void GetCConfig()
{
using(var instance = new cls1())
{
cls1.GrantAccess();
}
}
Finally, the following line is not needed, because _entities will always be null at the beginning of the constructor.
if (_entities == null)
{
I'd suggest reading some basic documentation about object oriented programming with c#, for example:
https://msdn.microsoft.com/en-us/library/dd460654.aspx

Initialize an instance of a class that has only Property type variables. JavaFX

I have a class that has some variables of SimpleStringProperty type. When this class is initialized by using a no argument constructor like this: Foo f = new Foo();, then the SimpleStringProperty variables are not initialized. Therefore I have to initialize that instance like this: Foo f = new Foo(null, null);
But, is there any other simple/clean way to initilize instance of such classes? I have also tried to extend the class like this:
public class Foo extends StringPropertyBase{//...},
but still no argument constructor doesn't initialize the variables.
Foo.java
public class Foo{
private SimpleStringProperty x;
private SimpleStringProperty y;
public Foo(String a, String b){
this.x = new SimpleStringProperty(a);
this.x = new SimpleStringProperty(b);
}
public StringProperty xProperty(){return x;}
public StringProperty yProperty(){return y;}
//...
}
Can't you just do something like this which initialises them to the empty string ""?
public Foo() {
this.x = new SimpleStringProperty("");
this.y = new SimpleStringProperty("");
}
Obviously this can be changed to provide any sane defaults you wish.
The properties can then be changed at another time by anything that is bound to it or by providing setters that allow the property to be updated, something like this:
public void setX(String value) {
this.xProperty().set(value);
}

Resources