MapStruct反向链接映射可能吗?

时间:2017-08-03 11:48:23

标签: java mapstruct

我是MapStruct的新手,无法在谷歌上找到我的问题的答案。 我有一个ShoppingCart,它有样品(以及其他属性),每个样品需要一个参考回到我的ShoppingCart。是否可以使用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

3 个答案:

答案 0 :(得分:1)

您可以像这样使用@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);
        }
    }
}

答案 1 :(得分:0)

您可以使用decorator并使用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)
        }
    }
}

答案 2 :(得分:0)

查看mapstruct-mapping-with-cycles存储库,它使用新的(从1.2.0开始)class Example<T> {} typealias Ex<T> = Example<T> // typealias for example class typealias L<T> = List<T> // typealias for Kotlin list class fun main(args: Array<String>) { Ex<Int>() // OK! compiles L<Int>(0,{ _ -> 1}) // unresolved reference } 来映射周期(这就是你所拥有的)。

这里的代码:

@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 ); } } 中的sourcetarget个对象可以是更具体的类型,不一定是CycleAvoidingMappingContext

映射器看起来像:

Object