Возможно ли сопоставление обратных ссылок MapStruct?

Я новичок в MapStruct и не смог найти ответ на свой вопрос в Google. У меня есть корзина покупок, в которой есть образцы (среди прочего), и каждому образцу нужна ссылка на мою корзину покупок. Можно ли сделать такое отображение с помощью MapStruct? Без MapStruct я просто передаю ссылку на ShoppingCart в Samples. Это было написано от руки:

protected ShoppingCart map(Cart cart, DataShareOption dataShareOption) {
//(other stuff)
   for (CartSample cartSample : cart.getCartSamples()) {
       ShoppingCartSample sample = mapCartSample(cartSample, shoppingCart,
       dataShareOption);
       shoppingCart.getSamples().add(sample);
   }
}

protected ShoppingCartSample mapCartSample(CartSample cartSample,
    ShoppingCart shoppingCart, DataShareOption dataShareOption) {

     ShoppingCartSample sample = new ShoppingCartSample();
     sample.setShoppingCart(shoppingCart);
     //(other stuff)
     return sample;
}

// the classes declarations:
// business class
public class ShoppingCart extends ShoppingCartHeader
{
    private List<ShoppingCartSample> samples = new   ArrayList<ShoppingCartSample>();
//rest of the class


// data base class:
@Entity
@Table(name = "cart")
public class Cart extends BaseEntity
{
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "cart")
private Set<CartSample> cartSamples = new HashSet<CartSample>();
   // more stuff here


// business class:
  public class ShoppingCartSample
  {
   private ShoppingCart shoppingCart;
  // rest of the class


// data base class:
@Entity
@Table(name = "cart_sample")
public class CartSample
{
   @ManyToOne()
   @JoinColumn(name = "cart_id")
   private Cart cart;
   // more stuff here

person gute Fee    schedule 03.08.2017    source источник
comment
Метод в вопросе создан вами или MapStruct?   -  person Filip    schedule 03.08.2017
comment
Содержит ли ShoppingCart ShoppingCartSample (ы)? У вас есть циклы, которые вы хотите отобразить? Можете ли вы показать упрощенный код ваших моделей? Мне нужна эта информация, чтобы я мог наиболее правильно ответить на вопрос, я не уверен, правильно ли я его понимаю в данный момент.   -  person Filip    schedule 03.08.2017
comment
Да, ShoppingCart содержит ShoppingCarSamples. И ShoppingCartSample содержит ShoppingCart. Думаю, это можно назвать циклом.   -  person gute Fee    schedule 04.08.2017
comment
@guteFee, не могли бы вы поделиться моделью?   -  person xenteros    schedule 04.08.2017
comment
@xenteros Я не понимаю вашего вопроса. Какая модель?   -  person gute Fee    schedule 04.08.2017
comment
Объявления ваших классов   -  person xenteros    schedule 04.08.2017
comment
@xenteros Я добавил объявления классов   -  person gute Fee    schedule 04.08.2017
comment
@guteFee, а что ты хочешь отобразить?   -  person xenteros    schedule 04.08.2017
comment
@xenteros Я хочу сопоставить корзину с ShoppingCart и CartSample с ShoppingCartSample   -  person gute Fee    schedule 04.08.2017


Ответы (3)


Вы можете использовать аннотацию @AfterMapping следующим образом:

@Mapper
public interface ShoppingCartMapper{
    ShoppingCart map(Cart cart);
    ShoppingCartSample map(CartSample cartSample);

    @AfterMapping
    default void setShoppingCartSampleParent(@MappingTarget ShoppingCart cart){
        for(ShoppingCartSample cartSample : cart.getSamples()){
            cartSample.setShoppingCart(cart);
        }
    }
}
person Tomer Gal    schedule 09.08.2018

вы можете использовать декоратор и установить ссылку самостоятельно с классом toher, вызывать автоматически с помощью mapstruct

твой картограф

@Mapper
@DecoratedWith(MyMapperDecorator.class)
public interface MyMapper {
    ShoppingCart map(Cart cart);
    ShoppingCartSample map(CartSample cart);
}

Ваш декоратор

public abstract class MyMapperDecorator implements MyMapper {
    private final MyMapper delegate;

    public ParticulierMapperDecorator(MyMapper delegate) {
        this.delegate = delegate;
    }

    public ShoppingCart map(Cart cart){
        ShoppingCart shoppingCart = delegate.map(cart);//map the two objects
        //Set your link
        for(ShoppingCartSample sample: hoppingCart.getSampes()){
            sample.setShoppingCart(shoppingCart)
        }
    }
}
person Bertrand Cedric    schedule 04.08.2017
comment
Это создаст цикл во время сопоставления. Сегодня я опубликую ответ, который следует использовать для отображения циклов. - person Filip; 04.08.2017

Взгляните на mapstruct-mapping-with-cycles. он использует новый (из 1.2.0) @Context для сопоставления циклов (что у вас есть).

Код здесь также:

public class CycleAvoidingMappingContext {
    private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();
    @BeforeMapping
    public <T> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
        return (T) knownInstances.get( source );
    }
    @BeforeMapping
    public void storeMappedInstance(Object source, @MappingTarget Object target) {
        knownInstances.put( source, target );
    }
}

Имейте в виду, что объекты source и target в CycleAvoidingMappingContext могут быть более конкретными типами, они не обязательно должны быть Object.

Маппер будет выглядеть так:

@Mapper
public interface MyMapper {
    ShoppingCart map(Cart cart, @Context CycleAvoidingMappingContext context);
    ShoppingCartSample map(CartSample cart, @Context CycleAvoidingMappingContext context);
}
person Filip    schedule 04.08.2017