Git Product home page Git Product logo

Comments (8)

jquested avatar jquested commented on July 22, 2024

Or alternatively, is there any support for inheritance?

from modelmapper.

jhalterman avatar jhalterman commented on July 22, 2024

Sorry I've been away for the past week. What would the desired behavior be for the UserModel/UserAccount example you gave? For an exception to be thrown since UserModel is an interface and not supported?

Also since you mentioned support for inheritance, how would you envision that working? If it feels like a separate feature, feel free to file a separate issue.

from modelmapper.

jquested avatar jquested commented on July 22, 2024

Thanks for the reply,

In truth, if the library doesn't support mapping to or from an interface or abstract class just mentioning it in the documentation would be fine. The reason why I think supporting interfaces it is important over some other (probably requested) features like automatic handling of lists is that most applications that work with DTOs normally do so with very clear interfaces so that systems can be separated cleanly. Orika has support for this for example.

The easiest case would be mapping FROM an interface (i.e. the case given). You've defined...

PropertyMap<UserModel,UserAccount>

...so ModelMapper would detect you have a mapping for UserModel(interface) -> UserAccount(bean) and map based on that. Currently it ignores the PropertyMap and looks at the implementation of the object you've passed to the map function - i.e. it looks for a mapping of UserModelImpl(bean that implements UserModel) -> UserAccount(bean).

As far as support for mapping from inheritance/abstract classes, this is essentially the same case. It would detect mappings for the objects you've defined PropertyMap and use the appropriate mapping unless a more specific mapping had been made for that exact object->object mapping.

from modelmapper.

dantonini avatar dantonini commented on July 22, 2024

I'm using modelMapper 0.6.1 & jooq in a quite big project.
I read http://modelmapper.org/user-manual/jooq-integration/ and I need of custom mappings.

I need to map org.jooq.Record to my business object using custom mapping.
But custom mappings seems to be completely ignored.

The only way I found to custom mapping works with org.jooq.Record is using implementation class org.jooq.impl.RecordImpl.

I have written a test that reproduced the problem without jooq dependencies.

Here the code:

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.modelmapper.ModelMapper;
import org.modelmapper.PropertyMap;
import org.modelmapper.convention.NameTokenizers;
import org.modelmapper.spi.ValueReader;

public class ModelMapperTest {
  static interface MyRecord {
    Object getValue(String name);

    Collection<String> names();
  }

  static class MyRecordImpl implements MyRecord {
    private Map<String, Object> map = new HashMap<String, Object>();

    @Override
    public Object getValue(final String name) {
      return map.get(name);
    }

    @Override
    public Collection<String> names() {
      return map.keySet();
    }

    void addValue(final String key, final Object obj) {
      map.put(key, obj);
    }
  }

  static class MyRecordReader implements ValueReader<MyRecord> {
    @Override
    public Object get(final MyRecord source, final String memberName) {
      Object value = source.getValue(memberName.toLowerCase());
      return value;
    }

    @Override
    public Collection<String> memberNames(final MyRecord source) {
      return source.names();
    }

    @Override
    public String toString() {
      return "jOOQ";
    }
  }

  static class OtherClass {
    private String asd;
    private String email;

    public String getAsd() {
      return asd;
    }

    public String getEmail() {
      return email;
    }

    public void setAsd(final String asd) {
      this.asd = asd;
    }

    public void setEmail(final String email) {
      this.email = email;
    }
  }

  private static MyRecord getMyRecord() {
    MyRecordImpl r = new MyRecordImpl();
    r.addValue("password_hash", "hash");
    r.addValue("email", "[email protected]");
    return r;
  }

  @Test
  public void modelMapperTest_shouldWorks() throws Exception {
    MyRecord r = getMyRecord();

    ModelMapper mp = new ModelMapper();
    mp.getConfiguration().addValueReader(new MyRecordReader());
    mp.getConfiguration().setSourceNameTokenizer(NameTokenizers.UNDERSCORE);
    mp.addMappings(new PropertyMap<MyRecord, OtherClass>() {
      @Override
      protected void configure() {
        map(source("password_hash")).setAsd(null);
        map(source("email")).setEmail(null);
      }
    });

    OtherClass c = mp.map(r, OtherClass.class);
    assertThat(c.getEmail(), is(r.getValue("email")));
    assertThat(c.getAsd(), is(r.getValue("password_hash")));
  }

  @Test
  public void modelMapperTest_works() throws Exception {
    MyRecord r = getMyRecord();

    ModelMapper mp = new ModelMapper();
    mp.getConfiguration().addValueReader(new MyRecordReader());
    mp.getConfiguration().setSourceNameTokenizer(NameTokenizers.UNDERSCORE);
    mp.addMappings(new PropertyMap<MyRecordImpl, OtherClass>() {
      @Override
      protected void configure() {
        map(source("password_hash")).setAsd(null);
        map(source("email")).setEmail(null);
      }
    });

    OtherClass c = mp.map(r, OtherClass.class);
    assertThat(c.getEmail(), is(r.getValue("email")));
    assertThat(c.getAsd(), is(r.getValue("password_hash")));
  }
}

from modelmapper.

jhalterman avatar jhalterman commented on July 22, 2024

@dantonini Yours is a good use case for interface (and actually, inheritance) mapping. You mentioned that you could only get custom mappings to work when using RecordImpl. ModelMapper can use custom mappings to map source Record instances:

https://github.com/jhalterman/modelmapper/blob/master/extensions/jooq/src/test/java/org/modelmapper/jooq/RecordValueReaderTest.java#L83

So perhaps you've hit on a different scenario. Can you post a test where this sort of thing isn't working for you using jOOQ Record/RecordImpl instances?

from modelmapper.

dantonini avatar dantonini commented on July 22, 2024

I've written a full eclipse maven test project to reproduce problematic behavior with jooq & model mapper.
Test use mysql as database.

I have attached zip file on post of jooq mailing list.
This is the url of the post
https://groups.google.com/forum/#!topic/jooq-user/B2QfKO3Quiw

you can download full project from
https://groups.google.com/group/jooq-user/attach/9c2ae98448d6bc1c/JooqModelMapperTest.zip?part=4&authuser=0

from modelmapper.

scottresnik avatar scottresnik commented on July 22, 2024

The issue I'm having is that my explicit mappings are not used if they are created with Interfaces as the destination types.

An example is here:
https://github.com/scottresnik/modelmapper-interfaces/tree/master/example.modelmapper

If I manually retrieve the TypeMap from my ModelMapper instance then call map on the returned TypeMap, the mapping works correctly.

A fix might be as simple as a map() overload on the ModelMapper class that takes a destination type, or source type depending on what one is trying to accomplish.

from modelmapper.

chhsiao90 avatar chhsiao90 commented on July 22, 2024

The TypeMap inheritance had been release on ModelMapper v1.0.0, please give it a try!

from modelmapper.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.