Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

matches multiple source property hierarchies problem #64

Closed
ACodeFarmer opened this issue Aug 12, 2013 · 15 comments
Closed

matches multiple source property hierarchies problem #64

ACodeFarmer opened this issue Aug 12, 2013 · 15 comments

Comments

@ACodeFarmer
Copy link

Hi, I'm using JPA(with Hibernate) and wish to convert some composite domain to view layer, So I'm using ModelMapper also.

At first, I defined some domain and DTO classes.

@Entity
public class User {
    ...
    @Id
    String id;

    @OneToOne
    Preference preference;
    ...
}

@Entity
public class Preference {
    ...
    @Id
    String id;

    @OneToOne
    User user;

    BigDecimal money;
    ...
}

public class UserDto {
    ...
    String id;
    BigDecimal preferenceMoney;
    ...
}

then, I've tried to mapping DTO object instance to domain object instance.

UserDto userDto = new UserDto();
userDto.setPreferenceMoney(1000.0);
mapper.map(userDto, User.class);

this code returns error

1) The destination property User.setPreference()/Preference.setUser() matches multiple source property hierarchies:

Skipping to set user to Preference class suppress this error, but when saving data to persist returned exception that preference object instance couldn't get user property. :(

Is this an another case of circular reference problem? I've dig circular reference test cases, but I can't find a solution.

@jhalterman
Copy link
Member

With just the example code you posted there shouldn't be a circular mapping problem. I tried to reproduce this in a simple test, but the test is passing fine right now. Have a look and let me know if I missed something:

https://github.com/jhalterman/modelmapper/blob/13f2f7e9b663c69efe7531d16804d3e7b0876837/core/src/test/java/org/modelmapper/bugs/GH64.java

@jedionmelbin
Copy link

jedionmelbin commented Apr 22, 2017

Dear, I have the same problem but with properties of duplicate type in each model I have properties with the same field.

  1. The destination property com.infiniteskills.domain.DTO.DocumentoIdentidadDTO.setDocumentoIdentidadId() matches multiple source property hierarchies:

    com.infiniteskills.domain.model.DocumentoIdentidad.getUsuarioCreacionId()
    com.infiniteskills.domain.model.DocumentoIdentidad.getUsuarioModificaId()

@chhsiao90
Copy link
Member

Thanks for the report.
Could you provide what it look like of the source class and the destination class?
Or maybe you can provide a minimum reproducer if you cannot provide the source class and destination class.
That will help us to solve your issue, thanks!

@dharaoza
Copy link

dharaoza commented Sep 5, 2017

I have the same problem can you please help me to solve.
The destination property com.measureone.vo.OrgApplicationPerson.setPersonParty()/com.measureone.vo.Party.setModifiedByPersonParty() matches multiple source property hierarchies:

com.measureone.dto.UserDTO.getModifiedByPersonPartyName()
com.measureone.dto.UserDTO.getModifiedByPersonPartyId()

@JuricaJaman
Copy link

i am not sure anymore to use modelmapper at all in 2018 still this problem exists

@mudassir047
Copy link

mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);

@franco148
Copy link

Still the problem exists. As the example provide by @ACodeFarmer I have my Jpa Entities with bidirectional relationships. So I am getting the following exception.

The destination property com..BaseEntity.setId() matches multiple source property hierarchies.........

The version of org.modelmapper that I am using is: 2.0.0

@chhsiao90
Copy link
Member

Is mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); working for you?
And could you please provide more detail about your source/destination class. Thanks.

@franco148
Copy link

franco148 commented Jun 1, 2018

Sure! I have the following:

My domain model:

@Data
@MappedSuperclass
public abstract class BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    @Column(nullable = false)
    private Boolean isDeleted;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FK_CreatedBy")
    private Participant createdBy;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FK_UpdatedBy")
    private Participant updatedBy;
}


@EqualsAndHashCode(callSuper = true)
@Data
@Entity
public class Comment extends BaseEntity {

    @Column(nullable = false)
    private Integer messagesAmount;

    @OneToOne(optional = false)
    @JoinColumn(name = "FK_Resource")
    private Resource commentedResource;
    
    .....
}


@Data
@Entity
public class Resource {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;
    @Enumerated(EnumType.STRING)
    private ResourceType type;
    
    @OneToOne(mappedBy = "commentedResource")
    private Comment comment;
    
    ......
}

My DTO:

@Getter
@Setter
public class CreateCommentDto {

    private Long commentedResourceId;
    private Long createdById;

    @JsonIgnore
    private LocalDateTime createdAt = LocalDateTime.now();
    @JsonIgnore
    private LocalDateTime updatedAt = LocalDateTime.now();
}

Calling my RestController from postman as following:

image

The result of the process is the following:

image

The example code where I am using the modelmapper is (I tested with other modelmapper configurations as well):

@Override
    public ResponseEntity<Comment> create(@RequestBody final CreateCommentDto commentDto) {
        //modelMapper.getConfiguration().setFieldMatchingEnabled(true);
        //modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        Comment converted = modelMapper.map(commentDto, Comment.class);
       
    .....
    }

Then I was also trying changing the name of the properties, as following:

@Getter
@Setter
public class CreateCommentDto {

    private Long resourceId;
    private Long createdById;

    @JsonIgnore
    private LocalDateTime createdAt = LocalDateTime.now();
    @JsonIgnore
    private LocalDateTime updatedAt = LocalDateTime.now();
}

image

Then I got the following:

image

Maybe something I am not implementing it in the right way, could you please help me to realize the issue?

Thanks in advance!

@chhsiao90
Copy link
Member

Thanks for the detailed information, I will investigate this bug.

@chhsiao90
Copy link
Member

hi @franco148 ,

One quick question: are below mappings that you expected?

createdById -> comment.id
resourceId -> comment.commentedResource.id

@franco148
Copy link

franco148 commented Jun 1, 2018

Sorry, I have not copied all the entities.

createdById : is the reference to a Participant entity. So, it would be comment.createdBy.Id
resourceId: yes, it refereces to comment.commentedResource.id

Here the missing entity.

@Data
@Entity
public class Participant {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @OneToMany(mappedBy = "sharedBy")
    private Set<ShareAction> shared;
    @OneToMany(mappedBy = "sharedWith")
    private Set<ShareAction> sharedWithMe;
    @OneToMany(mappedBy = "createdBy")
    private Set<Message> messages;
}

The diagram for these entities would be something like this.

image

So, in the controller I am calling a creation of a comment, which has a reference to a Recourse ID and Participant ID.

Hope that helps.

@chhsiao90
Copy link
Member

chhsiao90 commented Jun 2, 2018

hi @franco148 ,
Our matching strategy is not smart as you think, it has some rules, please refer matching-strategies for detail.
For mappings that our matching strategy can't support correctly, please try our property-mapping for customize mappings.

And it's weird that comment.createdAt is a LocalDateTime, I don't think it has a property named id.

@franco148
Copy link

Hi @chhsiao90

Sorry it was my mistake in the explanation, I have already updated that comment. comment.createdBy was the correct relation.

Thank you for your support. I will take a look at the resources you are suggesting me.

@thelebdev
Copy link

Anyone figure this out yet? 👁️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants