jmapper-framework / jmapper-core

Elegance, high performance and robustness all in one java bean mapper
http://jmapper-framework.github.io/jmapper-core
Apache License 2.0
231 stars 41 forks source link

How to use custom object factory #66

Open exports opened 7 years ago

exports commented 7 years ago

Hi there!

Recently I'm trying to switch my MapStruct based bean mappers to JMapper, and I'm just wondering how can I set factories for object like the @ObjectFactory do in MapStruct? I'm trying to create mappers for my spring-data-jpa entity dtos, when map dto to actual entity, I want to load the entity by id from database instead of initialize a new instance.

avurro commented 7 years ago

Hi @exports,

The request is not clear, could you write a sample code?

exports commented 7 years ago
@Entity class Foo {
  @Id private String id;
  @ManyToOne Bar bar;
}

@Entity class Bar {
  @Id private String id;
  @OneToMany Set<Bar> bars;
}

class FooDto {
  private String id;
  private BarDto bar;
}

class BarDto {
  private String id;
}

Both entities persisted in the database. When convert FooDto to Foo, I want to load the entity by id from database like entityManager.find(fooDto.getId(), Foo.class) or return a new instance if the entity not exists in database yet. In MapStruct 1.2.0.Beta, I can create a single ObjectFactory to manualy map a FooDto to Foo (as well as other entities) like this

@Component
public class PersistenceResolver {

  private EntityManager entityManager;

  public PersistenceResolver(EntityManager entityManager) {
    this.entityManager = entityManager;
  }

  @ObjectFactory
  public <T> T resolve(Resource resource, @TargetType Class<T> clazz) {
    String id = resource.getId();
    T entity = null;

    if (id == null) {
      try {
        entity = clazz.newInstance();
      } catch (IllegalAccessException | InstantiationException ignored) {
      }
    } else {
      entity = entityManager.find(clazz, id);
    }

    return entity;
  }
}

When converting dtos, the object mapper will call the ObjectFactory to extract a new instance of the given type instead of initialize a new one.

avurro commented 7 years ago

Hi @exports,

Currently there isn't a similar feature, will surely be included in the list of upcoming developments. You may probably find this page useful: https://github.com/jmapper-framework/jmapper-core/wiki/Immutable-Objects