Hibernate - mapowanie Entity na DTO przy relacji many-to-one

Hibernate - mapowanie Entity na DTO przy relacji many-to-one
AU
  • Rejestracja:ponad rok
  • Ostatnio:około rok
  • Postów:2
0

Witam,
Mam problem z mapowaniem, bo dla relacji one-to-one udało mi się rozgryźć jak to wykonać, to mam problem z relacją many-to-one.
Poniżej zamieszczam kod.

Kopiuj
@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;

    // gettery i settery
}
Kopiuj
@Entity
@Table(name = "VISIT")
public class VisitEntity {

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

	private String description;

	@ManyToOne(
			cascade = CascadeType.ALL,
			fetch = FetchType.LAZY
	)
	@JoinColumn(name = "patient_id")
	private PatientEntity patient;

    // gettery i settery
}
Kopiuj
public final class PatientMapper {
    public static PatientTO mapToTO(final PatientEntity patientEntity)
    {
        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)
    {
        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;
    }
}

Siedzę nad problemem relacji many-to-one od dłuższego czasu i nie mogę dojść jak napisać poprawnie mapowanie Entity-DTO oraz DTO-Entity.
Bardo bym prosił o pomoc jak stworzyć maper dla List<VisitEntity> visit.

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
2

Nie pisz tego mappera. Najprostsze rozwiązanie. Mapper Cię skrzywdzi.


jeden i pół terabajta powinno wystarczyć każdemu
BB
  • Rejestracja:ponad 2 lata
  • Ostatnio:około 5 godzin
  • Postów:66
0

A dlaczego ?

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
0

Dlaczego ?

  1. Takie mappery jak powyżej oparte o JavaBeany (gettery i settery) to proszenie się o nullpointery (zapomniane pola przy zmianach).
    Lepszym rozwiązaniem są tu record y (albo chociaż stare dobre niemutowalne obiekty).

  2. Hibernate / JPA to dramat, głównie z powodu debilnego dirty checking i niejawnego cyklu życia obiektu (z sygnatury/typu nie wiesz czy dostałeś managed czy detached), do tego z niejawną sesją/transakcją. To zwykle źródło upokorzeń podczas wszelkich refaktoringów (rzeczy zapisują się do bazy kiedy nie trzeba i nie zapisują kiedy trzeba, czasem leci jakies not initialized exception).
    Mappery niby mają trochę przed tym chronić, ale w praktyce wręcz zaciemniają tylko kod i tylko utrudniają nierówną walkę z hibernatem.

  3. ponad 90% mapperów to mappery 1 do 1. Przy zmianach entity wprowadza się takie same zmiany w DTO (chyba, że się zapomni). Nie mają one logicznego sensu, nic nie enapsulują, niczego de fakto nie izolują (coś jak gettery i settery) - takie pustokodzie.

  4. Są jeszcze mappery automatyczne, działające przez refleksję - imo najgorsze, bo dramatycznie utrudniają analizę problemów. (lepsze jednak ręczne za to z wymuszeniem jako takiej poprawności przez konstruktor - patrz punkt 1 ).


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 4x, ostatnio: jarekr000000
phantom_wizard
twierdzisz, że nie powinno się zatem w ogóle używać JPA?
jarekr000000
raczej, że nie warto. Są proste i sensowne alternatywy w Javie (JOOQ i JDBI) (gołe JDBC to nie jest sensowna alternatywa).
NO
A twórca JOOQ nie mówił czasem, że to nie jest alternatywa do ORM-a tylko bardziej do pisania skomplikowanych zapytań typu "select"?
jarekr000000
@Nofenak: nie wiem wszystkiego co mówił twórca JOOQ - chociaż miał wykład razem z Vladem - tam coś takiego mogło paść. Ale mi to i tak zwisa. Obecnie nie rozumiem jak można siebie krzywdzić i kod hibernatem. (A krzywdziłem tak z 15 lat).
Schadoow
No bo w jooq nie ma wielu elementów które masz w ormach. Np subkolekcje nie masz magi z bomby musisz pare linijek napisać a dodatkowo możesz to zrobić na pare sposobów w zależności jaki efekt w sql chcesz uzyskać. Dodatkowo mapping jedni powiedzą, że lubią mieć kontrole i lubia ręcznie pisać mappery drudzy powiedza, że chcieliby móc zrobić to adnotacjami. + wiele rzeczy jest dopiero w płatnej wersji jooq np GIS. Zrobiłem jeden większy projekt w jooq, który miał sporo grubych zapytań i tematy gisowe i mam mieszane uczucia. W kolejnym chce przetestować jdbi (nie ma gis :()
NO
  • Rejestracja:ponad 2 lata
  • Ostatnio:6 dni
  • Postów:135
0

Nie rób relacji dwukierunkowych. Zrób albo one-to-many albo many-to-one. Polecam się trzymać many-to-one, bo wtedy jest mniejszy coupling między encjami i łatwiej tym zarządzać. Pacjent nie musi wiedzieć o wszystkich swoich wizytach. Ważne, żeby każda wizyta wiedziała jakiego pacjenta dotyczy

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.