I want to get rid of the following code duplication within the MyFacadeBean. Consider the following situation:public class FacadeBean implements Facade {    @EJB    private CrudService crudService;    @Inject    private FirstAssembler firstAssembler;    @Inject    private SecondAssembler secondAssembler;    @Override    public void save(FirstValue value) {        FirstEntity entity = this.firstAssembler.transformToEntity(value);        this.crudService.persist(entity);    }    @Override    public void save(SecondValue value) {        SecondEntity entity = this.secondAssembler.transformToEntity(value);        this.crudService.persist(entity);    }}public interface MyFacade {    void save(FirstValue value);    void save(SecondValue value);}With the CrudService:public interface CrudService {    void persist(Object entity);}@Stateless@Local(CrudService.class)@TransactionAttribute(TransactionAttributeType.MANDATORY)public class CrudServiceBean implements CrudService {    public static final String PERSISTENCE_UNIT_NAME = my_persistence_unit;    private EntityManager entityManager;    @PersistenceContext(unitName = PERSISTENCE_UNIT_NAME)    public void setEntityManager(EntityManager entityManager) {        this.entityManager = entityManager;    }    @Override    public void persist(Object entity) {        this.entityManager.persist(entity);    }}With the following assemblers:public class FirstAssembler extends AbstractAssembler<FirstEntity> {    public FirstEntity transformToEntity(FirstValue value) {        if (value == null)            return null;        FirstEntity entity = new FirstEntity();        transformAbstractValueToAbstractObject(value, entity);        entity.setFixedRate(value.getFixedRate());        entity.setStartDate(value.getStartDate());        return entity;    }}public class SecondAssembler extends AbstractAssembler<SecondEntity> {    public SecondEntity transformToEntity(SecondValue value) {        if (value == null)            return null;        SecondEntity entity = new SecondEntity();        transformAbstractValueToAbstractObject(value, entity);        entity.setTransactionType(value.getTransactionType());        entity.setValueDate(value.getValueDate());        return entity;    }}public abstract class AbstractAssembler<T extends AbstractEntity> {    protected void transformAbstractValueToAbstractObject(AbstractValue value, T object) {        object.setUniqueId(value.getUniqueId());        object.setNominalAmountValue(value.getNominalAmountValue());    }}With the following entities:@Entitypublic class FirstEntity extends AbstractEntity {    private static final long serialVersionUID = 1L;    @Id    @Column(name = ID)    private Long id;    @Column(name = START_DATE)    @Temporal(TemporalType.DATE)    private Date startDate;    @Column(name = FIXED_RATE)    @Digits(integer = 1, fraction = 10)    private BigDecimal fixedRate;    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public Date getStartDate() {        return startDate;    }    public void setStartDate(Date startDate) {        this.startDate = startDate;    }    public BigDecimal getFixedRate() {        return fixedRate;    }    public void setFixedRate(BigDecimal fixedRate) {        this.fixedRate = fixedRate;    }}@Entitypublic class SecondEntity extends AbstractEntity {    private static final long serialVersionUID = 1L;    @Id    @Column(name = ID)    private Long id;    @Column(name = VALUE_DATE)    @Temporal(TemporalType.DATE)    private Date valueDate;    @Column(name = TRANSACTION_TYPE)    @Enumerated(EnumType.STRING)    private TransactionType transactionType;    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public Date getValueDate() {        return valueDate;    }    public void setValueDate(Date valueDate) {        this.valueDate = valueDate;    }    public TransactionType getTransactionType() {        return transactionType;    }    public void setTransactionType(TransactionType transactionType) {        this.transactionType = transactionType;    }}@MappedSuperclasspublic abstract class AbstractEntity implements Serializable {    private static final long serialVersionUID = 1L;    @Column(name = TRANSACTION_NOM_AMOUNT_VALUE)    @Digits(integer = 18, fraction = 5)    @Min(0)    private BigDecimal nominalAmountValue;    public BigDecimal getNominalAmountValue() {        return nominalAmountValue;    }    public void setNominalAmountValue(BigDecimal nominalAmountValue) {        this.nominalAmountValue = nominalAmountValue;    }}I tried the following approach:public class FacadeBean implements Facade {    @Inject    private Assembler assembler;    @Inject    private AssemblerFactory assemblerFactory;    @Override    public <T extends AbstractValue> void save(T value) {        Assembler assembler = assemblerFactory.createAssembler(value);        AbstractEntity entity = assembler.transformToEntity(value);        this.crudService.persist(entity);    }}Problems are the AssemblerFactoryImpl and the AssemblerImpl in which I have to do instanceOf checks and castings...Another idea would be to let the value know which transformer to use (or how to transform). But I want the value to be dumb.
Find the appropriate transformer for an abstract value
java;design patterns;polymorphism