Search code examples
javahibernaterelationship

How to map many-to-one relationship?


I have a problem with map many-to-one relationship. When I create mapper for one-to-one, that's OK.

@Entity
@Table(name = "PATIENT")
public class PatientEntity {

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

    @Column(nullable = false)
    private String firstName;

    @OneToOne(
            cascade = CascadeType.ALL,
            fetch = FetchType.LAZY,
            optional = false
    )
    private AddressEntity address;

    @OneToMany(mappedBy = "patient")
    private List<VisitEntity> visit;

My mapper for one-to-one relationship:

public final class PatientMapper {
    public static PatientTO mapToTO(final PatientEntity patientEntity)
    {
        if (patientEntity == null)
        {
            return null;
        }
        final PatientTO patientTO = new PatientTO();
        patientTO.setId(patientEntity.getId());
        patientTO.setFirstName(patientEntity.getFirstName());

        final AddressTO addressTO = new AddressTO();
        addressTO.setId(patientEntity.getAddress().getId());
        addressTO.setCity(patientEntity.getAddress().getCity());

        patientTO.setAddress(addressTO);

        return patientTO;
    }

    public static PatientEntity mapToEntity(final PatientTO patientTO)
    {
        if(patientTO == null)
        {
            return null;
        }
        PatientEntity patientEntity = new PatientEntity();
        patientEntity.setId(patientTO.getId());
        patientEntity.setFirstName(patientTO.getFirstName());

        AddressEntity addressEntity = new AddressEntity();
        addressEntity.setId(patientTO.getAddress().getId());
        addressEntity.setCity(patientTO.getAddress().getCity());

        patientEntity.setAddress(addressEntity);

        return patientEntity;
    }
}

How to build code for many-to-one relationship [private List<VisitEntity> visit]?

Thank you in advance for your help.


Solution

  • You need to map the List<VisitEntity> in your PatientEntity to List<VisitTO> in your PatientTO and vice-versa. I'm assuming you also have a VisitMapper that maps between VisitEntity and VisitTO.

    For example:

    import java.util.List;
    import java.util.stream.Collectors;
    
    public final class PatientMapper {
        public static PatientTO mapToTO(final PatientEntity patientEntity)
        {
            if (patientEntity == null)
            {
                return null;
            }
            final PatientTO patientTO = new PatientTO();
            patientTO.setId(patientEntity.getId());
            patientTO.setFirstName(patientEntity.getFirstName());
    
            final AddressTO addressTO = new AddressTO();
            addressTO.setId(patientEntity.getAddress().getId());
            addressTO.setCity(patientEntity.getAddress().getCity());
            
            // Map VisitEntity list to VisitTO list
            List<VisitTO> visitTOs = patientEntity.getVisits()
                .stream()
                .map(VisitMapper::mapToTO)
                .collect(Collectors.toList());
            patientTO.setVisits(visitTOs);
    
            patientTO.setAddress(addressTO);
    
            return patientTO;
        }
    
        public static PatientEntity mapToEntity(final PatientTO patientTO)
        {
            if(patientTO == null)
            {
                return null;
            }
            PatientEntity patientEntity = new PatientEntity();
            patientEntity.setId(patientTO.getId());
            patientEntity.setFirstName(patientTO.getFirstName());
    
            AddressEntity addressEntity = new AddressEntity();
            addressEntity.setId(patientTO.getAddress().getId());
            addressEntity.setCity(patientTO.getAddress().getCity());
            
            // Map VisitTO list to VisitEntity list
            List<VisitEntity> visitEntities = patientTO.getVisits()
                .stream()
                .map(VisitMapper::mapToEntity)
                .collect(Collectors.toList());
            patientEntity.setVisits(visitEntities);
    
            patientEntity.setAddress(addressEntity);
    
            return patientEntity;
        }
    }
    

    This modification assumes that you have a VisitMapper class with mapToTO and mapToEntity methods for VisitEntity and VisitTO. If you don't have this, you will need to create it similarly to your AddressMapper.

    Still, remember to set the patient in each VisitEntity when you are mapping from VisitTO to VisitEntity, otherwise you will lose the link back to the patient.