0

I have a Customers table that has AddressEmbedded in it.

I also have a hardcoded table Countries where I already have a region for every country, country is the primary key.

I want to join AddressEmbedded and Countries so I used the ManyToOne and put CountryEntity in AddressEmbedded.

But I'm getting an error that mapstruct can't generate setCountry.

So the question is, how do I make AddressEmbedded.setCountry(string country)? It's supposed to do a call to the db to get the corresponding region for that country, but it seems wrong to add a db call in a setter.

Here are the entity definitions:

    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    @Data
    @Embeddable
    public class AddressEmbedded {

        @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "country")
        private CountryEntity country;
    }
    @Data
    @Entity
    @Table(name = "Countries")
    public class CountryEntity {

        @Id
        @Column(name = "country")
        private String country;

        @Column(name = "region")
        private String region;
    }
    @Data
    @Entity
    @Table(name = "Customers")
    public class CustomerEntity {
        @Embedded
        private AddressEmbedded address;
    }
shinzou
  • 5,850
  • 10
  • 60
  • 124
  • You won't be able to pass ```String``` to ```AddressEmbedded.setCountry```. It looks like you need to lookup ```CountryEntity``` by ID (```country```) and then pass it to ```AddressEmbedded.setCountry```. – Petr Aleksandrov Dec 04 '19 at 17:39
  • A lookup in a setter? – shinzou Dec 04 '19 at 17:51
  • I personally believe it's bad practice to place any logic to getters/setters. Related topic: https://stackoverflow.com/questions/44600536/is-it-bad-design-if-we-add-logic-in-getter-and-setter-of-entity-class – Petr Aleksandrov Dec 04 '19 at 18:10
  • Of course, that's why I asked this question, I don't want to add a db call in the setter. – shinzou Dec 04 '19 at 19:39

1 Answers1

-1

This was solved with mapstruct mappings

    @Mappings(
            @Mapping(target = "address.country", source = "countryEntity")
    )
    CustomerEntity fromSubmitCustomerDetailsRequestToCustomerEntity(SubmitCustomerDetailsRequest request, CountryEntity countryEntity);

    @Mappings(
            @Mapping(target = "address.country", source = "customerEntity.address.country.country")
    )
    GetCustomerDetailsResponse fromCustomerEntityToGetCustomerDetailsResponse(CustomerEntity customerEntity);

I have the CountryEntity in fromSubmitCustomerDetailsRequestToCustomerEntity because before I call it I validate that I have a country that exists.

shinzou
  • 5,850
  • 10
  • 60
  • 124